Linux系统下调用动态库(.so)
1、linuxany.c代码如下:
1
2
3
4
5
6
7
8
|
#include "stdio.h" void display( char * msg){ printf ( "%s\n" ,msg); } int add( int a, int b){ return a+b; } |
2、编译c代码,最后生成Python可执行的.so文件
(1)gcc -c linuxany.c,将生成一个linuxany.o文件
(2)gcc -shared linuxany.c -o linuxany.so,将生成一个linuxany.so文件
3、在Python中调用
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/python from ctypes import * import os / / 参数为生成的.so文件所在的绝对路径 libtest = cdll.LoadLibrary(os.getcwd() + '/linuxany.so' ) / / 直接用方法名进行调用 print libtest.display( 'Hello,I am linuxany.com' ) print libtest.add( 2 , 2010 ) |
4、运行结果
1
2
|
Hello,I am linuxany.com 2012 |
Windows下Python调用dll
python中如果要调用dll,需要用到ctypes模块,在程序开头导入模块 import ctypes
由于调用约定的不同,python调用dll的方法也不同,主要有两种调用规则,即 cdecl和stdcal,还有其他的一些调用约定,关于他们的不同,可以查阅其他资料
先说 stdcal的调用方法:
方法一:
1
2
|
import ctypes dll = ctypes.windll.LoadLibrary( 'test.dll' ) |
方法二:
1
2
|
import ctypes dll = ctypes.WinDll( 'test.dll' ) |
cdecl的调用方法:
1.
1
2
3
4
|
import ctypes dll = ctypes.cdll.LoadLibrary( 'test.dll' ) ##注:一般在linux下为test.o文件,同样可以使用如下的方法: ## dll = ctypes.cdll.LoadLibrary('test.o') |
2.
1
2
|
import ctypes dll = ctypes.CDll( 'test.dll' ) |
看一个例子,首先编译一个dll
导出函数如下:
1
2
3
4
5
6
7
8
9
10
|
# define ADD_EXPORT Q_DECL_EXPORT extern "C" ADD_EXPORT int addnum( int num1, int num2) { return num1+num2; } extern "C" ADD_EXPORT void get_path( char *path){ memcpy (path, "hello" , sizeof ( "hello" )); } |
这里使用的是cdecl
脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
dll = ctypes.CDLL( "add.dll" ) add = dll.addnum add.argtypes = [ctypes.c_int,ctypes.c_int] #参数类型 add.restypes = ctypes.c_int #返回值类型 print add( 1 , 2 ) get_path = dll.get_path get_path.argtypes = [ctypes.c_char_p] path = create_string_buffer( 100 ) get_path(path) print path.value |
结果如下:
我们看到两个结果,第一个是进行计算,第二个是带回一个参数。
当然我们还可以很方便的使用windows的dll,提供了很多接口
1
2
3
4
5
6
|
GetSystemDirectory = windll.kernel32.GetSystemDirectoryA buf = create_string_buffer( 100 ) GetSystemDirectory(buf, 100 ) print buf.value MessageBox = windll.user32.MessageBoxW MessageBox( None , u "Hello World" , u "Hi" , 0 ) |
运行结果如下: