Найти - Пользователи
Полная версия: Модуль ctypes
Начало » Python для экспертов » Модуль ctypes
1
NoN
Допустим есть dll скомпилированная, вот ее код
#include "stdafx.h"
#include "windows.h"



int aas(
{

MessageBoxA(0,"buf","sdf",0);
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
return TRUE;
}
Как вызвать с помощь модуля ctypes функцию aas()?

Пробывал так:
import ctypes
lib=ctypes.windll.LoadLibrary('name.dll')
print lib
lib.aas()
выдает:
<WinDLL ‘name.dll’, handle d90000 at b17ff0>
а дальше ошибку
Traceback (most recent call last):
File "dll.py", line 4, in <module>
lib.aas()
File "M:\python\Lib\ctypes\__init__.py", line 361, in __getattr__
func = self.__getitem__(name)
File "M:\python\Lib\ctypes\__init__.py", line 366, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'aas' not found
shiza
Я правда Си плохо помню, но не может ли это быть связано с отсуствием аргументов?
PooH
Я тоже плохо помню С, но разве функция не должна как-то помечатся как экспортируемая?
NoN
shiza
Я правда Си плохо помню, но не может ли это быть связано с отсуствием аргументов?
не. вывод должен быть примерно таким
<_FuncPtr object at 0x0097DAF8>
NoN
PooH
Я тоже плохо помню С, но разве функция не должна как-то помечатся как экспортируемая?
Точно, попробую исправить
NoN
В dll перед функцией aas добавил __declspec(dllexport), заработало.
Только из из скрипа функция по имени не вызывается почему то, а вызывается так lib

не работает
import ctypes
lib=ctypes.windll.LoadLibrary('name.dll')
lib.aas()
работает
import ctypes
lib=ctypes.windll.LoadLibrary('name.dll')
lib[1]
PooH
У меня сейчас нет под рукой windows, чтобы попробовать, тем не менее похоже проблема в вашей DLL. Это точно C? помнится С++ добавляет символы подчеркивания перед именами и надо использовать __cdecl
Андрей Светлов
Да. Это - mangling имен. И если файл назывался blahblah.cpp - то это С++ а не С. Имена кодируются по другому. В С - подчеркивание вначале, в С++ - довольно сложная схема. Проще всего увидеть просто открыв файл и поискав aas. Все слово будет именем - с цифрами и значками. Еще можно написать extern “C” __declspec(dllexport) void aas(); - форсирует использование С стиля.
PooH
__cdecl служит немножко не для того. Он определяет процедуру передачи параметров и получения ответа. Конкретно cdecl - параметры ложаться в стек справа налево, результат в eax, вызыватель чистит стек. Добавленное подчеркивание - это мелочь, которая к тому же меняется в зависимости от С/С++.
Есть еще stdcall и fastcall. Без extern “C” указание calling conversion недостаточно.
PooH
Андрей Светлов
PooH
__cdecl служит немножко не для того.
Ну я же говорил, что плохо помню. Тем не менее источник ошибки то указал верно ;)
NoN
Всем спасибо, все получилось.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB