我正在把一个文件从python2转换成python3,这个文件使用ctypes
模块调用一个C函数,下面这个最小的例子在python2中是有效的,但是在python3(3.11)中会产生如下错误:
错误:异常:写入0x0000000000094E0时发生访问冲突
// mydll.c
#include <stdio.h>
void myfunc(char* c, int i, char* c2) {
printf("Hello World");
}
int main() {
return 0;
}
# foo.py
import ctypes
import sys
PY3 = sys.version_info.major == 3
if PY3:
clibrary = ctypes.WinDLL("mydll.dll", winmode=1)
else:
clibrary = ctypes.WinDLL("mydll.dll")
prototype = ctypes.CFUNCTYPE(None, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p)
c1 = (ctypes.c_char * 512)()
i = ctypes.c_int(0)
c2 = (ctypes.c_char * (600 * 8))()
func = prototype(("myfunc", clibrary))
func(c1, i, c2)
我认为这与不同python版本之间字符串的unicode和bytes表示有关.从我收集的信息来看,这看起来像是取消引用一个空指针或类似的东西.我试过使用ctypes.create_string_buffer()
,但遇到了同样的错误.
我希望相同的代码在python2和python3中都能工作。是什么导致了python3错误?
1条答案
按热度按时间sqougxex1#
在Windows上,winmode 参数用于指定如何装入库(因为忽略了 mode)。它采用对Win32 API
LoadLibraryEx
flags参数有效的任何值。如果省略,默认值是使用导致最安全的DLL加载的标志,以避免诸如DLL劫持之类的问题。传递DLL的完整路径是确保加载正确的库和依赖项的最安全方法。注意不要使用此值;它仅用于向后兼容**。如果您计划仅访问DLL中的数据或资源,请使用LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE或LOAD_LIBRARY_AS_IMAGE_RESOURCE或同时使用这两个函数。否则,请使用LoadLibrary函数将库作为DLL或可执行模块加载。
所以,去掉 winmode(或者将其设置为支持的值),应该就可以了。
你的例子(稍微调整了一下):
输出:
备注: