推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
explist
V2EX  ›  Python

调用 API 函数,出现 OSError 错误:access violation reading 0xC ?

  •  
  •   explist · Sep 20, 2017 · 9131 views
    This topic created in 3339 days ago, the information mentioned may be changed or developed.

    DLL 函数内部调用了 PYthon ; DLL 函数在 C++中调用一切正常;

    然后,在 py 中通过 ctypes 模块再来反调用此 DLL 函数(出口转内销?),就会抛异常:

       OSError: exception: access violation reading 0x0000000C
    

    以上,是何原因?

    #-----------encode.py-----------------

    def myencode(wcs):

         if isinstance(wcs,str):
              return wcs.encode()
         return wcs
    

    #----------------------------------------

    // c++中原型:

    char* encode(const wchar_t* wcs)

    {

    Py_Initialize();
    if(!Py_IsInitialized()) return NULL;
    
    using pyPtr = PyObject*;
    pyPtr pmod = PyImport_ImportModule("encode");    // 调用 encode.py 模块
    pyPtr pfunc = PyObject_GetAttrString(pmod,"myencode");  //encode.myencode
    pyPtr pargs = Py_BuildValue("(u)",wcs);
    
    pyPtr pres = PyEval_CallObject(pfunc,pargs);
    char * r;
    PyArg_Parse(pres,"y",&r);
    
    Py_Finalize();
    return r;    
    

    }

    #----------------------------------------------

    #--- 最后是 PY 中的测试代码 test.py----

    from ctypes import CDLL

    path = r'c:\test\Myencode.dll'

    dll = CDLL(path)

    dll.encode.restype = c_char_p

    print( dll.encode("中华人民共和国") )

    Supplement 1  ·  Sep 21, 2017

    def myencode(wcs):

        if isinstance(wcs,str):
            return wcs.encode('gbk')  #  GBK
        return wcs
    
    12 replies  •  2018-07-04 11:54:43 +08:00
    vainl1
    vainl1
    Sep 21, 2017 via iPhone
    1
    初学 c 语言,可能说的不对,题主参考下这个: https://zh.m.wikipedia.org/zh-hans/Volatile%E5%8F%98%E9%87%8F ,把 r 声明为 staic char * r 试试?
    explist
    explist
    OP
    Sep 21, 2017
    2
    这样设计也不行:

    def myencode():
    print("encode_func...")
    #------------------------------------
    int encode ( )
    {
    Py_Initialize();
    if(!Py_IsInitialized()) return 1;

    int flg = PyRun_SimpleString("import encode as ls\nls.myencode()");

    Py_Finalize();
    return flg;
    }
    #-----------------------------------

    #--- 最后是 PY 中的测试代码 test.py----

    from ctypes import CDLL

    path = r'c:\test\Myencode.dll'

    dll = CDLL(path)

    print( dll.encode() ) # 这里还是会抛类似的异常(只是地址不同)
    explist
    explist
    OP
    Sep 21, 2017
    3
    @vainl1
    地址打不开?
    vainl1
    vainl1
    Sep 21, 2017 via iPhone
    4
    @explist wiki 中文需要梯子,对应英文的地址: https://en.m.wikipedia.org/wiki/Volatile_(computer_programming) 。你改了试了么?
    explist
    explist
    OP
    Sep 21, 2017
    5
    @vainl1
    还是不行,二楼就能说明问题不能这样解决
    指针本身是复制的
    NoAnyLove
    NoAnyLove
    Sep 22, 2017
    6
    问题解决了吗?
    explist
    explist
    OP
    Sep 22, 2017
    7
    @NoAnyLove
    没解决呢
    NoAnyLove
    NoAnyLove
    Sep 22, 2017
    8
    @explist 查到原因了吗? 0xc 访问异常,肯定是指针传递错误了,基本上就从参数传递、调用约定几个地方找问题了。
    explist
    explist
    OP
    Sep 22, 2017
    9
    @NoAnyLove py 中用的 CDLL 与 GCC 中的默认调用约定一致;至于说参数传递,2 楼处不传任何参数的函数有同样的异常,也能说明问题
    explist
    explist
    OP
    Sep 22, 2017
    10
    PY 解释器被多次初始化?
    a65071627
    a65071627
    Feb 1, 2018
    11
    @explist 你好,我也遇到了你同样的问题, 请问你解决了吗?
    explist
    explist
    OP
    Jul 4, 2018
    12
    @a65071627 没找到原因
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3369 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 10:11 · PVG 18:11 · LAX 02:11 · JFK 05:11
    ♥ Do have faith in what you're doing.