python在c dll中
我刚刚创建了一个带有python的dll。 当我用python函数导出功能时,我无法在Python代码中调用它 但是,当我内部没有python代码的情况下导出经典的C函数时,它可以很好地工作。我不明白
c dll
#include <stdio.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
__declspec(dllexport) PyObject* getList()
{
PyObject *PList = PyList_New(0);
PyList_Append(PList, Py_BuildValue("i", 1));
return PList;
}
python代码
import ctypes
lib = ctypes.cdll.LoadLibrary("EasyProtect.dll")
getList = lib.getList
getList.argtypes = None
getList.restype = ctypes.py_object
print(getList())
我的错误
print(getList())
OSError: exception: access violation reading 0x0000000000000010
I just created a DLL in C with Python in it.
When I export my function with python functions in it, I can't call it in my Python code
But when I export a classic C function without Python code inside, it works perfectly. I don't understand
C DLL
#include <stdio.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
__declspec(dllexport) PyObject* getList()
{
PyObject *PList = PyList_New(0);
PyList_Append(PList, Py_BuildValue("i", 1));
return PList;
}
Python Code
import ctypes
lib = ctypes.cdll.LoadLibrary("EasyProtect.dll")
getList = lib.getList
getList.argtypes = None
getList.restype = ctypes.py_object
print(getList())
My Error
print(getList())
OSError: exception: access violation reading 0x0000000000000010
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 [python.docs]:class ctypes.pypes.pydll(name,mode = default = default_mode = default_mode = default_mode = default_mode = default_mode = default_mode = default_mode = default_mode = default_mode = default_mode ,hander = none)(强调是我的):
因此,您应该用 pydll ( pydll )替换 cdll ( cdll )。
我加强了您的示例。
dll00.c :
code00.py :
输出:
According to [Python.Docs]: class ctypes.PyDLL(name, mode=DEFAULT_MODE, handle=None) (emphasis is mine):
So, you should replace cdll (CDLL) by pydll (PyDLL).
I enhanced your example a bit.
dll00.c:
code00.py:
Output:
当您使用Python C API时,必须保留GIL(全球解释器锁)。为此使用
pydll
。加载您的DLL:顺便说一句,您的DLL具有参考泄漏。
py_buildvalue
返回一个新对象,pylist_append
将其添加到列表时会增加引用。PY_DECREF
应在py_buildvalue返回的对象上调用
。但是,在这种情况下,使用所需的大小创建列表,并使用
pylist_set_item
,该列表窃取了新对象的引用以初始化列表,并已对初始化新列表项目进行了优化:When you use the Python C API, the GIL (global interpreter lock) must be held. Use
PyDLL
for that. Load your DLL with:As an aside, your DLL has a reference leak.
Py_BuildValue
returns a new object, andPyList_Append
increments the reference when adding it to the list.Py_DECREF
should be called on the object returned byPy_BuildValue
.In this case, though, create the list with the size you want and use
PyList_SET_ITEM
which steals the new object's reference to initialize the list and is optimized for initializing new list items: