所以,我有以下文件:
添加一个.c
long int addone(long int x){
return x+1;
}
然后通过GCC 7.2.0的Windows安装编译成DLL(我也尝试使用英特尔C++编译器,在将函数更改为^ {CD1>}之后,但这不会改变当我尝试将其加载到Python中时的结果):
gcc -c addone.c
gcc -shared -o addone.dll addone.o
然后我尝试将其加载到python 3.6.7中:
import ctypes
_addone = ctypes.CDLL("addone.dll")
虽然我设法得到了CDLL对象,但它缺少函数“addone”。我尝试过使用ctypes.WinDLL()
和ctypes.windll.LoadLibrary
方法导入C DLL,但是这些方法都实现了相同的最终结果:我从ctypes中获得了一个不具有公共方法的对象,并且私有方法(在Python对象中,而不是DLL中)似乎都与addone函数无关。你知道吗
为了再次检查我的编译器是否按我的预期运行,我反汇编了结果DLL,它看起来像一个典型的DLL。在内部,函数甚至没有名称损坏:
0000000530ce1030 <add_one>:
530ce1030: 55 push %rbp
530ce1031: 48 89 e5 mov %rsp,%rbp
530ce1034: 48 89 4d 10 mov %rcx,0x10(%rbp)
530ce1038: 48 8b 45 10 mov 0x10(%rbp),%rax
530ce103c: 48 83 c0 01 add $0x1,%rax
530ce1040: 5d pop %rbp
530ce1041: c3 retq
530ce1042: 90 nop
<Everything between these two instructions is just more no-ops>
530ce104f: 90 nop
我已经能够在Unix系统上实现这一点,并且在该平台上将cdll与Python接口也没有问题。然而,搬到Windows上,我觉得我遗漏了一些东西。即使在不同的机器上尝试所有这些,我仍然无法访问我编写的函数。你知道吗
我觉得我错过了什么。我做错什么了?你知道吗
经过一番摆弄,我知道发生了什么事。你知道吗
函数确实已经正确地编写,正确地编译成DLL,并且ctypes.CDLL文件对象创建正确。你知道吗
那个ctypes.CDLL文件对象没有立即“看到”函数名,因此它不在方法列表中。我所做的就是忽略了方法不在对象的名称空间中这一事实,于是我大胆地调用了
_addone.addone(x)
。这使对象意识到函数在DLL中,并将其添加到名称空间中。你知道吗我怀疑ctypes中存在一些后端,调用函数会导致它检查库中是否确实存在该名称。也许这是为了防止名称空间被编译器放入DLL的各种其他函数弄乱。你知道吗
尝试导出函数:
并生成头文件
addone.h
:相关问题 更多 >
编程相关推荐