How can I use a DLL from Python

0

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 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()

I get the below error:

"WindowsError: exception: access violation reading 0x0000002D"

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

python
dllimport
ctypes
asked on Stack Overflow Feb 23, 2011 by Sam • edited Feb 23, 2011 by David Heffernan

5 Answers

4

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.

answered on Stack Overflow Feb 23, 2011 by Jeremy Whitlock
1

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.

answered on Stack Overflow Feb 23, 2011 by Adam Rosenfield
0

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

answered on Stack Overflow Feb 23, 2011 by inspectorG4dget
0

There is also Boost::Python

answered on Stack Overflow Feb 23, 2011 by Fábio Diniz
0

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.

answered on Stack Overflow Feb 24, 2011 by Sam

User contributions licensed under CC BY-SA 3.0