Python: ctypes加载的dll是否共享同一内存space
Python: do dlls loaded by ctypes share the same memory space
我正在尝试用 Python 中的 dll 做一些我知道我可以用 C++ 做的事情,但是我遇到了内存异常。
如果在 C++ 中加载两个 dll 并为它们提供相同的指针,它们都可以毫无问题地操作指针指向的对象。
当使用 Python 和 cytypes 做同样的事情时,创建对象的 dll 绝对可以在后续调用中取消引用该指针,因此在 [=28= 之间传递该指针] 并且 C++ dll 工作正常。但是,当以相同方式将此指针提供给第二个 dll 时,我得到一个非常无用的异常:"WindowsError: exception: access violation reading 0x0101CC84".
在我开始尝试调试这些 dll 之前(这会很痛苦),有谁知道 Python 是否将这些 C++ dll 加载到同一内存中 space?
是的,python.exe是进程,所有DLL都加载到它的内存中space。
您的 .argtypes
和 restype
声明可能不正确(或根本没有声明)。这是一个有效的例子:
x.c
__declspec(dllexport) const char* func1()
{
return "hello";
}
y.c
#include <stdio.h>
__declspec(dllexport) void func2(const char* s)
{
printf("%s\n",s);
}
Python
>>> from ctypes import *
>>> x = CDLL('x')
>>> x.func1.argtypes = None
>>> x.func1.restype = c_void_p
>>> y = CDLL('y')
>>> y.func2.argtypes = [c_void_p]
>>> y.func2.restype = None
>>> s = x.func1()
>>> hex(s)
'0x7ff8b4ca8000'
>>> y.func2(s)
hello
请注意,我明确声明了参数 c_void_p
,因为 ctypes
会在输出时将 c_char_p
转换为 Python 字符串,并将 Python 字符串转换为char*
在输入上,因此不能证明同一个指针可以从一个 DLL 传递到另一个 DLL。
可以使用像 SysInternals Process Explorer 这样的工具来查看进程中的 DLL space:
请注意,x.func1()
返回的地址在 x.dll
的映射范围内,y.func2(s)
显示正确。
我正在尝试用 Python 中的 dll 做一些我知道我可以用 C++ 做的事情,但是我遇到了内存异常。
如果在 C++ 中加载两个 dll 并为它们提供相同的指针,它们都可以毫无问题地操作指针指向的对象。
当使用 Python 和 cytypes 做同样的事情时,创建对象的 dll 绝对可以在后续调用中取消引用该指针,因此在 [=28= 之间传递该指针] 并且 C++ dll 工作正常。但是,当以相同方式将此指针提供给第二个 dll 时,我得到一个非常无用的异常:"WindowsError: exception: access violation reading 0x0101CC84".
在我开始尝试调试这些 dll 之前(这会很痛苦),有谁知道 Python 是否将这些 C++ dll 加载到同一内存中 space?
是的,python.exe是进程,所有DLL都加载到它的内存中space。
您的 .argtypes
和 restype
声明可能不正确(或根本没有声明)。这是一个有效的例子:
x.c
__declspec(dllexport) const char* func1()
{
return "hello";
}
y.c
#include <stdio.h>
__declspec(dllexport) void func2(const char* s)
{
printf("%s\n",s);
}
Python
>>> from ctypes import *
>>> x = CDLL('x')
>>> x.func1.argtypes = None
>>> x.func1.restype = c_void_p
>>> y = CDLL('y')
>>> y.func2.argtypes = [c_void_p]
>>> y.func2.restype = None
>>> s = x.func1()
>>> hex(s)
'0x7ff8b4ca8000'
>>> y.func2(s)
hello
请注意,我明确声明了参数 c_void_p
,因为 ctypes
会在输出时将 c_char_p
转换为 Python 字符串,并将 Python 字符串转换为char*
在输入上,因此不能证明同一个指针可以从一个 DLL 传递到另一个 DLL。
可以使用像 SysInternals Process Explorer 这样的工具来查看进程中的 DLL space:
请注意,x.func1()
返回的地址在 x.dll
的映射范围内,y.func2(s)
显示正确。