Как я могу использовать DLL из Python - PullRequest
0 голосов
/ 23 февраля 2011

Я пытаюсь загрузить DLL в Python, я хочу использовать ее функцию eConnect (), используя ctypes

Что я знаю из исходного кода DLL:

  • из исходного кода * .cpp: bool eConnect( const char *host, UINT port, int clientId=0);
  • из инструмента для обхода зависимостей: порядковый номер функции равен 6, а недокументированное имя -
    ?eConnect@EClientSocket@@UAE_NPBDIH@Z

Я пытался получить доступ к eConnect двумя способами: myfunction и myfunction2, но, возможно, я ошибся. Вот мой код:

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: исключение: чтение прав доступа 0x0000002D»

Мне бы здесь нужна была помощь (я не знаю с ++). Спасибо!

Ответы [ 5 ]

4 голосов
/ 23 февраля 2011

Чтобы сделать вещи проще, Pythonic, вы, возможно, захотите заглянуть в ctypesgen:

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

Он сгенерирует подходящие функции-оболочки, типы данных и тому подобное для вас.Если вы просто хотите знать, как использовать ctypes, можете начать с учебника:

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

Что-нибудь более конкретное, и мне придется прочитать API для DLL, которую выПытаешься использовать.

1 голос
/ 23 февраля 2011

Экспортируемая функция является функцией-членом класса EClientSocket.Вы пытаетесь вызвать эту функцию из Python без передачи указателя EClientSocket в качестве параметра this;Более того, ctypes ничего не знает о __thiscall соглашении о вызовах, поэтому даже если вы передадите экземпляр EClientSocket, он будет в стеке, а не в регистре ECX.

реальным решением этой проблемы было бы экспортировать оболочку C из вашей DLL, которая перенаправляет вызов на eConnect.Например:

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

Однако даже в этом случае вы должны быть очень осторожны на стороне Python, чтобы создать соответствующий экземпляр EClientSocket.Я настоятельно рекомендую пересмотреть ваш подход здесь.

0 голосов
/ 24 февраля 2011

Спасибо за ваши ответы всем.Я принял совет Адама и пересмотрел мой подход.Поскольку я не знаю, знаю c ++, это была плохая идея с самого начала.

В R существует альтернативный API (не официальный), который построен поверх официального API Java.Тогда довольно просто связать R и Python, используя rPy2.

0 голосов
/ 23 февраля 2011

Существует также Boost :: Python

0 голосов
/ 23 февраля 2011

Рассмотрим IronPython . Это облегчает вызов файлов DLL.

...