重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
ctypes: 可直接调用c语言动态链接库。
10余年的安宁网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网整合营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整安宁建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联从事“安宁网站设计”,“安宁网站推广”以来,每个客户项目都认真落实执行。
使用步骤:
1 编译好自己的动态连接库
2 利用ctypes载入动态连接库
3 用ctype调用C函数接口时,需要将python变量类型做转换后才能作为函数参数,转换原则见下图:
4 Python若想获取ctypes调用的C函数返回值,需要先指定返回值类型。我们将在接下来的完整Sample中看到如何使用。
#Step 1: test.c#include stdio.h
int add(int a, int b)
{
return a + b;
}#Step 2: 编译动态链接库 ( 如何编译动态链接库在本文不详解,网上资料一大堆。)gcc -fPIC -shared test.c -o libtest.so
#Step 3: test.py
from ctypes import *mylib = CDLL("libtest.so") 或者 cdll.LoadLibrary("libtest.so") add = mylib.add
add.argtypes = [c_int, c_int] # 参数类型,两个int(c_int是ctypes类型,见上表)
add.restype = c_int # 返回值类型,int (c_int 是ctypes类型,见上表)
sum = add(3, 6)
在函数声明加入前缀,如
__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类型的对照,如下:
二、Python调用C/C++\x0d\x0a\x0d\x0a\x0d\x0a1、Python调用C动态链接库\x0d\x0a\x0d\x0a Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。\x0d\x0a(1)C语言文件:pycall.c\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0a/***gcc -o libpycall.so -shared -fPIC pycall.c*/ \x0d\x0a#include \x0d\x0a#include \x0d\x0aint foo(int a, int b) \x0d\x0a{ \x0d\x0a printf("you input %d and %d\n", a, b); \x0d\x0a return a+b; \x0d\x0a} \x0d\x0a(2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern "C"来进行编译。\x0d\x0a(3)Python调用动态库的文件:pycall.py\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0aimport ctypes \x0d\x0all = ctypes.cdll.LoadLibrary \x0d\x0alib = ll("./libpycall.so") \x0d\x0alib.foo(1, 3) \x0d\x0aprint '***finish***' \x0d\x0a(4)运行结果:\x0d\x0a\x0d\x0a\x0d\x0a2、Python调用C++(类)动态链接库 \x0d\x0a\x0d\x0a 需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern "C",构建后的动态链接库没有这些函数的符号表。\x0d\x0a(1)C++类文件:pycallclass.cpp\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0a#include \x0d\x0ausing namespace std; \x0d\x0a \x0d\x0aclass TestLib \x0d\x0a{ \x0d\x0a public: \x0d\x0a void display(); \x0d\x0a void display(int a); \x0d\x0a}; \x0d\x0avoid TestLib::display() { \x0d\x0a cout \x0d\x0ausing namespace std; \x0d\x0aint test() \x0d\x0a{ \x0d\x0a int a = 10, b = 5; \x0d\x0a return a+b; \x0d\x0a} \x0d\x0aint main() \x0d\x0a{ \x0d\x0a cout \x0d\x0a#include \x0d\x0a#include \x0d\x0a \x0d\x0aint fac(int n) \x0d\x0a{ \x0d\x0a if (n
回答于 2022-11-16
Python可以调用VC的模块。
Python调用C++在Python脚本里添加其中ctypes是Python的一个库,提供和C语言兼容的数据类型,可以很方便地调用CDLL中的函数。运行以上脚本得到:显示调用C++程序成功。
采用这个方法,我们不用进行大量的改写,也能在Python中使用我们积累的各种C++程序了。