2014-01-17 4 views
0

Я должен использовать dll C++ с использованием MFC, и я бы хотел назвать его из python. Эта библиотека содержит этот заголовок в файле .hC++ dll, вызываемый из Python

LONG CommOpen(BYTE port, LONG baud_rate);

Тогда я вижу в свободном ПО dllexp, что моя функция называется? CommOpen @ CFIPcmd @@ QAEJEJ @ Z в бинарный файл, ошибка не сообщается, когда я в питоне

import ctypes

lib = ctypes.WinDLL('C:\Users\toto\FIProtocol.dll')

prototype = WINFUNCTYPE(c_long, c_byte, c_long)

testPt = ctypes.WINFUNCTYPE (prototype)

testApi = testPt (("[email protected]@@[email protected]", lib))

до тех пор пока оно не похоже на работу, но я хотел бы назвать в Python эквивалент в C++ из

Long l= CommOpen(5 ,115200);

но я не плавника d знаю, как действовать. Любая помощь будет действительно оценена!

ответ

3

Учитывая информацию, представленную в этом вопросе, решение:

import ctypes 

lib = ctypes.CDLL(r'C:\Users\toto\FIProtocol.dll') 
CommOpen = getattr(lib, "[email protected]@@[email protected]") 
CommOpen.argtypes = [c_byte, c_long] 
CommOpen.restype = c_long 

И теперь он готов назвать:

l = CommOpen(5 ,115200) 

Некоторые примечания:

  1. Используйте CDLL, а не WinDLL, потому что функция использовала соглашение о назначении по умолчанию cdecl.
  2. Используйте getattr, чтобы иметь возможность указать поврежденное имя.
  3. Обязательно указывать argtypes и restype явно.

Однако, выясняется, что у вас есть гораздо большая проблема. Выше было написано на основе того, что ваша функция является функцией, не являющейся членом. Что является разумным предположением, поскольку ctypes требует, чтобы функции были либо нечленными, либо статическими.

Однако, когда я кладу к управляемому имя функции в demanger (например http://pear.warosu.org/c++filtjs/), кажется, что эта функция на самом деле:

public: long __thiscall CFIPcmd::CommOpen(unsigned char,long) 

То есть функция-член объекта C++. К этому нельзя обратиться с ctypes. Вам нужно создать обычную оболочку стиля C или найти другой способ взаимодействия.

+0

Ну, кажется, очень хорошо, но я получаю >>> L = CommOpen (5, 115200) Traceback (самый последний вызов последнего): Файл "", строка 1, в WindowsError: исключение: запись нарушения доступа 0x1D1C5504, но почему? –

+0

Разделите проблему на две части. Напишите простую DLL, содержащую функцию с тем же именем и параметрами, и вызовите ее из Python. Попросите его вызывать ['MessageBeep'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms680356 (v = vs.85) .aspx) N раз. Это работает, DLL, вероятно, терпит неудачу, потому что не находит какого-либо предположения о среде, в которой она была создана для запуска. – ixe013

+1

См. Мое обновление. Вы никогда не сможете вызвать эту функцию из ctypes. –

0

В соответствии с http://docs.python.org/2/library/ctypes.html#calling-functions «Вы можете вызывать эти функции, как любой другой Python, вызываемый». Я бы предложил запустить интерактивную консоль Python (например, ipython) и проверить ее самостоятельно.

Ну, я только что установили питона в VirtualBox Win32 и проверил пример:

 
>>> from ctypes import * 
>>> f = getattr(cdll.msvcrt, "[email protected]@Z") 
>>> f 
<_FuncPtr object at 0x00B7EDC8> 
>>> f() 
24969248 
>>> _ 

Так что, да, вы можете вызывать эти функции объектов, как и любой другой функции в среде Python. Так же, как документация утверждает :)

Аналогично _cputws работы:

 
>>> cputws = getattr(cdll.msvcrt, "_cputws") 
>>> r = cputws("Hello, World!\n") 
Hello, World! 
>>> r 
0 
>>> 
+0

Как вы можете видеть, моя функция распознается только с именем, найденным в двоичном файле dll: CommOpen @ CFIPcmd @@ QAEJEJ @ Z, который содержит специальные символы. Таким образом, я не могу называть его прямо в консоли python, используя lib.functiontocall .. должен быть другой способ –

+0

Отредактирован ответ и приведен еще несколько примеров. – user3159253

+0

>>> е() Traceback (самый последний вызов последнего): Файл "", строка 1, в ValueError: процедура, вероятно, вызывается не достаточно аргументов (8 байт отсутствует) >>> е (5, 115200) Traceback (последний звонок последний): Файл «», строка 1, in WindowsError: exception: запись нарушения доступа 0x1D1C5504 спасибо, но как я могу назвать этот API аргументами, которые я хочу? –

Смежные вопросы