V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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 · 2017-09-20 23:21:33 +08:00 · 7705 次点击
    这是一个创建于 2403 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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("中华人民共和国") )

    第 1 条附言  ·  2017-09-21 12:01:47 +08:00

    def myencode(wcs):

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

    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
        3
    explist  
    OP
       2017-09-21 12:02:24 +08:00
    @vainl1
    地址打不开?
    vainl1
        4
    vainl1  
       2017-09-21 12:04:53 +08:00 via iPhone
    @explist wiki 中文需要梯子,对应英文的地址: https://en.m.wikipedia.org/wiki/Volatile_(computer_programming) 。你改了试了么?
    explist
        5
    explist  
    OP
       2017-09-21 15:41:09 +08:00
    @vainl1
    还是不行,二楼就能说明问题不能这样解决
    指针本身是复制的
    NoAnyLove
        6
    NoAnyLove  
       2017-09-22 07:52:00 +08:00
    问题解决了吗?
    explist
        7
    explist  
    OP
       2017-09-22 11:01:38 +08:00
    @NoAnyLove
    没解决呢
    NoAnyLove
        8
    NoAnyLove  
       2017-09-22 11:04:20 +08:00
    @explist 查到原因了吗? 0xc 访问异常,肯定是指针传递错误了,基本上就从参数传递、调用约定几个地方找问题了。
    explist
        9
    explist  
    OP
       2017-09-22 11:17:42 +08:00
    @NoAnyLove py 中用的 CDLL 与 GCC 中的默认调用约定一致;至于说参数传递,2 楼处不传任何参数的函数有同样的异常,也能说明问题
    explist
        10
    explist  
    OP
       2017-09-22 11:19:57 +08:00
    PY 解释器被多次初始化?
    a65071627
        11
    a65071627  
       2018-02-01 09:20:05 +08:00
    @explist 你好,我也遇到了你同样的问题, 请问你解决了吗?
    explist
        12
    explist  
    OP
       2018-07-04 11:54:43 +08:00
    @a65071627 没找到原因
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1075 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:11 · PVG 07:11 · LAX 16:11 · JFK 19:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.