折腾了很久,网上也少有找到关于参数引用的方法。
以下,为方便其他人参考 对主要问题的解决方式作以记录。
1. 参数传入和传出
如test.so中有如下接口:
int DLLAPI_ChangeValue(int *value,char *cstr);
接口实现:
int DLLAPI_ChangeValue(int *value,char *cstr)
{
value = 123;
strcpy(cstr,"abc");
return 1;
}
python 调用代码中对于传入的value值需要做指针处理。
from ctypes import *
lib = CDLL(test.so)
lib.DLLAPI_ChangeValue.argtypes = (c_char_p,POINTER(c_int)) #argtypes 声明参数类型
lib.DLLAPI_ChangeValue.restype = (c_int) #restype 声明返回值类型
value = POINTER(c_int)(c_int(0))
cstr = c_char_p("")
#接口调用
ret = lib.DLLAPI_ChangeValue(value,cstr)
#print ret ; 得到 1
#print value ; 得到 123
#print cstr.value ; 得到 "abc"
诸如此类,其他类型对应转换 详见ctypes官网文档 中对类型转换的说明。
2. 操作库和依赖库的加载
项目中需要调用的动态库(操作库)与python执行文件不在同一目录,并且操作库有几个第三方依赖库。
你可能想到常用的方式,在执行前使用
export LD_LIBRARY_PATH="..." #指定依赖库路径
这种方式虽然可以写一个 .sh 启动脚本,先设置LD_LIBRARY_PATH 再启动程序去完成,但是不够简洁方便。
直接在python代码中完成设置:
import os,sys
# 依次判断两种情况。如果两个判断放一个if中,第一个判断成立的时候第二个判断会有KeyError的报错
if 'LD_LIBRARY_PATH' not in os.environ.keys():
os.environ['LD_LIBRARY_PATH'] = path
os.execv(sys.argv[0], sys.argv)
elif path not in os.environ['LD_LIBRARY_PATH']:
os.environ['LD_LIBRARY_PATH'] = path
os.execv(sys.argv[0], sys.argv)
from ctypes import *
lib = CDLL(test.so)
'''
实现调用逻辑
'''