开发者

How can I use a DLL from Python

I am trying to load a DLL in Python, I want to use its eConnect() function using ctypes

What I know from the source code of the DLL:

  • from the *.cpp source code: bool eConnect( const char *host, UINT port, int clientId=0);
  • from the dependency walker tool: function ordinal is 6 and undecorated name is

    ?eConnect@EClientSocket@@UAE_NPBDIH@Z

I tried to access the eConnect from two ways myfunction and myfunction2, but I probably get it wrong. Here is my code:

from c开发者_开发百科types 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()

I get the below error:

"WindowsError: exception: access violation reading 0x0000002D"

I would badly need some help here (I do not know c++). Thanks!


To make things easier, more Pythonic, you might want to look into ctypesgen:

http://code.google.com/p/ctypesgen/

It will generate proper wrapper functions, data types and such for you. If you just want to know how to use ctypes, might as well start with the tutorial:

http://docs.python.org/library/ctypes.html

Anything more specific and I'll have to read the API for the DLL you're attempting to use.


The function being exported is a class member function of the class EClientSocket. You're attempting to call that function from Python without passing in an EClientSocket pointer as the this parameter; furthermore, ctypes doesn't know anything about the __thiscall calling convention, so even if you did pass in an EClientSocket instance, it would be on the stack instead of in the ECX register.

The only real solution to this would be to export a C wrapper from your DLL that forwards the call to eConnect. For example:

extern "C" DLLEXPORT
bool EClientSocket_eConnect(EClientSocket *This, const char *host, UINT port, int clientId)
{
    return This->eConnect(host, port, clientId);
}

However, even in that case, you have to be extra-careful on the Python side to construct an appropriate EClientSocket instance. I'd strongly recommend reconsidering your approach here.


Consider looking into IronPython. It makes it easier to call on DLL files.


There is also Boost::Python


Thanks for your answers everyone. I took Adam's advise and reconsidered my approached. As I do not know know c++, it was a bad idea from the start.

There is an alternative API in R (not official) which is built on top of the official Java API. It is then quite easy to link R and Python using rPy2.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜