python怎么调用dll共享库

Python014

python怎么调用dll共享库,第1张

可以的,python中一般有两种方法调用DLL中的函数。1.直接使用函数名,函数名可以用dependencywalker等工具查看。(这个工具在vc或者vs的工具包中)[python]viewplaincopyimportctypesdll=CTYPES.CDLL("test.dll")res=test(3,4)2.使用Ordinal,Ordinal可以用dependencywalker等工具查看。[python]viewplaincopyimportctypesdll=CTYPES.CDLL("test.dll")res=dll[1](3,4)

python引用DLL文件的方法具体分析如下:

在python中调用dll文件中的接口比较简单,如我们有一个test.dll文件,内部定义如下:

extern "C"

{

int __stdcall test( void* p, int len)

{

return len

}

}

在python中我们可以用以下两种方式载入

1.

import ctypes

dll = ctypes.windll.LoadLibrary( 'test.dll' )

2.

import ctypes

dll = ctypes.WinDll( 'test.dll' )

其中ctypes.windll为ctypes.WinDll类的一个对象,已经在ctypes模块中定义好的。在test.dll中有test接口,可直接用dll调用即可

nRst = dll.test( )

print nRst

由于在test这个接口中需要传递两个参数,一个是void类型的指针,它指向一个缓冲区。一个是该缓冲区的长度。因此我们要获取到python中的字符串的指针和长度

#方法一:

sBuf = 'aaaaaaaaaabbbbbbbbbbbbbb'

pStr = ctypes.c_char_p( )

pStr.value = sBuf

pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value

nRst = dll.test( pVoid, len( pStr.value) )

#方法二:

test = dll.test

test.argtypes = [ctypes.c_char_p, ctypes.c_int]

test.restypes = ctypes.c_int

nRst = test(sBuf, len(sBuf))

如果修改test.dll中接口的定义如下:

extern "C"

{

int __cdecl test( void* p, int len)

{

return len

}

}

由于接口中定义的是cdecl格式的调用,所以在python中也需要用相应的类型

1.

import ctypes

dll = ctypes.cdll.LoadLibrary( 'test.dll' )

##注:一般在linux下为test.o文件,同样可以使用如下的方法:

##dll =ctypes.cdll.LoadLibrary('test.o')

2.

import ctypes

dll = ctypes.CDll( 'test.dll' )

在函数声明加入前缀,如

__declspec(dllexport) int Fun(int a, int b)

否则在加载该dll时会提示找不到该符号

在windows下可以通过vs自带的dumpbin工具查看可被调用符号

dumpbin /exports test.dll

C函数在调用过程中关于参数传递和压栈由多种规定,作为dll提供给其他程序调用时,必须明确并统一为同一种调用规定,否则会导致栈破坏,编译器负责具体实现调用规定,主要有以下几种调用规定

python下调用C库有多种方式,ctypes是其中一种比较方便的,调用时首先需要加载dll文件,根据C dll的调用规定不同需要使用不同接口,使用ctypes需要 import ctypes 库

对于简单的C函数,例如 int add(int a, int b) , 此时就可以直接调用了,如

对于较复杂的C函数的参数情况,ctypes调用时对入参和出餐做一定处理,这里分情况讨论

以上包含了几种主要的参数传递情况,ctypes也提供了一个较为完整的python类型和C类型的对照,如下: