我如何使用Python中的DLL

时间:2011-02-23 18:09:59

标签: python dllimport ctypes

我正在尝试在Python中加载DLL,我想使用ctypes

来使用其eConnect()函数

我从DLL的源代码中了解到:

  • 来自* .cpp源代码:bool eConnect( const char *host, UINT port, int clientId=0);
  • 来自依赖性walker工具的
  • :函数序数为6,未修饰的名称为
    ?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 ++)。 谢谢!

5 个答案:

答案 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非常容易。