我正在尝试在Python中加载DLL,我想使用ctypes
来使用其eConnect()函数我从DLL的源代码中了解到:
bool eConnect( const char *host, UINT port, int clientId=0);
?eConnect@EClientSocket@@UAE_NPBDIH@Z
我尝试从myfunction和myfunction2两种方式访问eConnect,但我可能错了。这是我的代码:
from ctypes import *
def main():
IP = c_char_p('127.0.0.1')
port = c_uint(7496)
client_id = c_int(0)
myfunction = getattr(cdll.TwsSocketClient, "?eConnect@EClientSocket@@UAE_NPBDIH@Z")
myfunction2= cdll.TwsSocketClient[6]
print myfunction
print myfunction2
print myfunction(IP, port, client_id,IP)
if __name__ == "__main__":
main()
我收到以下错误:
“WindowsError:exception:access violation reading 0x0000002D”
我非常需要一些帮助(我不知道c ++)。 谢谢!
答案 0 :(得分:4)
为了让事情更容易,更多Pythonic,你可能想看看ctypesgen:
http://code.google.com/p/ctypesgen/
它将为您生成适当的包装函数,数据类型等。如果您只是想知道如何使用ctypes,那么也可以从教程开始:
http://docs.python.org/library/ctypes.html
任何更具体的内容,我都必须阅读您尝试使用的DLL的API。
答案 1 :(得分:1)
正在导出的函数是类EClientSocket
的类成员函数。您试图从Python调用该函数而不传入EClientSocket
指针作为this
参数;此外,ctypes对__thiscall
调用约定一无所知,所以即使你确实传入EClientSocket
实例,它也会在堆栈而不是ECX寄存器中。
唯一真正的解决方案是从DLL中导出一个C包装器,它将调用转发给eConnect
。例如:
extern "C" DLLEXPORT
bool EClientSocket_eConnect(EClientSocket *This, const char *host, UINT port, int clientId)
{
return This->eConnect(host, port, clientId);
}
但是,即使在这种情况下,您也必须在Python方面格外小心,以构建适当的EClientSocket
实例。我强烈建议您在此重新考虑您的方法。
答案 2 :(得分:0)
考虑研究IronPython。它可以更容易地调用DLL文件。
答案 3 :(得分:0)
答案 4 :(得分:0)
感谢大家的回答。我接受了亚当的建议并重新考虑了我的接近。由于我不知道c ++,从一开始就是一个坏主意。
在R(非官方)中有一个替代API,它建立在官方Java API之上。然后使用rPy2链接R和Python非常容易。