通过ctypes 库调用 C语言的*.so库
假如有个libtest.so
test.h
#include "stdio.h"
typedef int( *callback)( const char *sessionInfo, int msgID, void *userData );
void test(int *value);
void testCallBack(int type,callback call);
test.c
#include "test.h"
void test(int *value)
{
printf("value=%d\n",*value);
}
void testCallBack(int type,callback call)
{
if(type==0)
{
call("我是回调函数",1,"Hello");
}
else
printf("测试。。");
}
生成so
gcc test.c -fPIC -shared -o libtest.so
3
、编译参数解析
最主要的是 GCC 命令行的一个选项 :
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
python调用 生成的libtest.so
demo.py
#coding=utf-8
from ctypes import *
so=pydll.LoadLibrary('./libtest.so')
err_code=pointer(c_int(5))#传递指针参数
so.test(err_code)
#回调函数
def CallBackFunc(Info,ID,Data):
print "Info: %s, ID: %d ,Data: %s" %(Info,ID,Data)
return 0
CMPRESULTFUNC = CFUNCTYPE(c_int, c_char_p, c_int,c_void_p)
callback=CMPRESULTFUNC(CallBackFunc)
so.testCallBack(0,callback)
python 注册回调 是通过 CFUNCTYPE
第一个参数是python回调函数的返回值,如果没有就是None。
第二个及其以后的就是python回调函数的参数类型了。
CMPRESULTFUNC = CFUNCTYPE(c_int, c_char_p, c_int,c_void_p)//创建一个c函数类型的对象工厂
callback=CMPRESULTFUNC(CallBackFunc)根据Python可调用对象生成函数
运行 :
python demo.py