Использование dll из Python

Май 13, 2007, 15:19

Во­об­ще ис­поль­зо­ва­ние dll из Python осо­бой про­бле­мой не яв­ля­ет­ся, для это­го есть мо­дуль ctypes, ко­то­рый, на­чи­ная с Python 2.5, вхо­дит в со­став это­го са­мо­го Python’а. Но по ка­кой-то за­га­доч­ной при­чине даже вез­де­су­щий Google не смог най­ти при­ме­ра связ­ки "своя dll" + "своя python про­грам­ма", а там есть неко­то­рые неоче­вид­ные граб­ли: ко­гда "своя dll" бу­дет под­клю­чать­ся к чему угод­но, но Python бу­дет ра­пор­то­вать:

ValueError: Procedure called with not enough arguments (N bytes missing)
or wrong calling convention

Или го­во­рить, что он ва­ших функ­ций в упор не ви­дит.

Так что, как го­во­рят буд­ди­сты, на бла­го всех жи­вых су­ществ!

sam­pdll.def (без него Python не уви­дит на­ших функ­ций):

LIBRARY    "sampdll"

EXPORTS
SomeFunc1
SomeFunc2
SomeFunc3

sam­pdll.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <windows.h>

BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID)
{
return TRUE;
}

extern "C" __declspec (dllexport) double SomeFunc1(double a)
{
return a+1.1;
}

extern "C" __declspec (dllexport) void SomeFunc2(int& a)
{
a = a+10;
}

extern "C" __declspec (dllexport) void SomeFunc3(int len, int* a)
{
for ( int i = 0; i < len; i++ )
a[i] += 100;
}

Вы­зы­ва­ем:

>>> from ctypes import *
>>> a = CDLL("C:\sampdll.dll")
>>> a
<CDLL 'C:\sampdll.dll', handle f10000 at bba990>

Функ­ция по­лу­ча­ет и воз­вра­ща­ет dou­ble:

>>> a.SomeFunc1.restype = c_double
>>> print "SomeFunc1:", a.SomeFunc1(c_double(1.1))
SomeFunc1: 2.2

Функ­ция по­лу­ча­ет и из­ме­ня­ет пе­ре­мен­ную по ссыл­ке:

>>> arg = c_int(10)
>>> a.SomeFunc2(byref(arg))
12230088 # Загадка :)
>>> print "SomeFunc2:", arg.value
SomeFunc2: 20

Функ­ция из­ме­ня­ет мас­сив:

>>> arr_lst = [1,2,3,4,100]
>>> arr_type = c_int * len(arr_lst)
>>> arr = arr_type(*arr_lst)
>>> a.SomeFunc3(len(arr_lst), arr)
5 # Еще одна :)
>>> for i in arr: print i

101
102
103
104
200

Про все осталь­ное мож­но про­чи­тать в до­ку­мен­та­ции. Ис­ход­ни­ки все­го что выше тут. Dll со­би­ра­лась Vi­su­al C++ 2005.

blog comments powered by Disqus
Сергей Лымарь © 2005-2014, Все права защищены.