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("中华人民共和国") )
def myencode(wcs):
if isinstance(wcs,str):
return wcs.encode('gbk') # GBK
return wcs
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 试试?
|
2
explist OP 这样设计也不行:
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() ) # 这里还是会抛类似的异常(只是地址不同) |
4
vainl1 2017-09-21 12:04:53 +08:00 via iPhone
@explist wiki 中文需要梯子,对应英文的地址: https://en.m.wikipedia.org/wiki/Volatile_(computer_programming) 。你改了试了么?
|
6
NoAnyLove 2017-09-22 07:52:00 +08:00
问题解决了吗?
|
9
explist OP @NoAnyLove py 中用的 CDLL 与 GCC 中的默认调用约定一致;至于说参数传递,2 楼处不传任何参数的函数有同样的异常,也能说明问题
|
10
explist OP PY 解释器被多次初始化?
|