Linux下Python调用C语言

一:Python调用C语言场景

1,已经写好的C语言代码,不容易用Python实现,想直接通过Python调用写好的C语言代码

2,C比Python快(只是从语言层面,不能绝对说C程序就是比Python快)

3,想直接调用C语言丰富的库

二:Python的CTypes库

Python中调用C语言不止一种方法,常见的有:

1.SWIG,编写一个额外的接口文件来作为SWIG(终端工具)的入口

2.通过CTypes调用

3.使用Python/C API方法

但是 CTypes是最简单上手的一种,本文将用CTypes来演示如何在Python中调用C

可以先看看CTypes支持的类或者方法

>>> import ctypes
>>>
>>> dir(ctypes)
['ARRAY', 'ArgumentError', 'Array', 'BigEndianStructure', 'CDLL', 'CFUNCTYPE', 'DEFAULT_MODE', 'LibraryLoader', 'LittleEndianStructure', 'POINTER', 'PYFUNCTYPE', 'PyDLL', 'RTLD_GLOBAL', 'RTLD_LOCAL', 'SetPointerType', 'Structure', 'Union', '_CFuncPtr', '_FUNCFLAG_CDECL', '_FUNCFLAG_PYTHONAPI', '_FUNCFLAG_USE_ERRNO', '_FUNCFLAG_USE_LASTERROR', '_Pointer', '_SimpleCData', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_c_functype_cache', '_calcsize', '_cast', '_cast_addr', '_check_size', '_ctypes_version', '_dlopen', '_endian', '_memmove_addr', '_memset_addr', '_os', '_pointer_type_cache', '_reset_cache', '_string_at', '_string_at_addr', '_sys', '_wstring_at', '_wstring_at_addr', 'addressof', 'alignment', 'byref', 'c_bool', 'c_buffer', 'c_byte', 'c_char', 'c_char_p', 'c_double', 'c_float', 'c_int', 'c_int16', 'c_int32', 'c_int64', 'c_int8', 'c_long', 'c_longdouble', 'c_longlong', 'c_short', 'c_size_t', 'c_ssize_t', 'c_ubyte', 'c_uint', 'c_uint16', 'c_uint32', 'c_uint64', 'c_uint8', 'c_ulong', 'c_ulonglong', 'c_ushort', 'c_void_p', 'c_voidp', 'c_wchar', 'c_wchar_p', 'cast', 'cdll', 'create_string_buffer', 'create_unicode_buffer', 'get_errno', 'memmove', 'memset', 'pointer', 'py_object', 'pydll', 'pythonapi', 'resize', 'set_errno', 'sizeof', 'string_at', 'wstring_at']
>>>
 

其中cdll类对于我们接下来调用C非常有用处,我们通过help来查看cdll类,可以看到可以通过LoadLibrary来加载C的库(在Linux中是.so,在windows中是.dll)


三:实战

1,调用C语言的函数

首先我们在C语言中实现三个简单函数

#include<stdio.h>void cprintf()
{printf("Hello word!\n");return;
}int add(int a, int b)
{return a+b;
}int cscanf()
{int a;int b;scanf("%d %d",&a,&b);return a+b;
}

三个函数,一个是有打印函数,一个是有传参函数,一个是有输入函数,将C编译成动态库

gcc -fPIC -c ctest.c  -o ctest.o
gcc -shared -o libctest.so ctest.o

 

然后我们在Python中调用这三个函数,

from ctypes import *cLib = cdll.LoadLibrary('./libctest.so')cLib.cprintf()a = 1
b = 2
sum = cLib.add(a,b)
print(f'{a}+{b}={sum}')cSum = cLib.cscanf()
print(f'cSum={cSum}')

 运行

可以看到运行结果与我们想要的结果一致

2,调用C语言返回值是指针的函数

C代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define uint8_t   unsigned char
#define uint16_t  unsigned shorttypedef struct TagMyStruct
{char name[10];uint8_t age;int score;
} MyStruct,*MyStructPointer;MyStructPointer cstruct_get_data_pointer() // 返回结构体指针
{MyStructPointer pt = (MyStructPointer)malloc(sizeof(MyStructPointer));strcpy(pt->name, "ftz");pt->age = 18;pt->score = 88;return pt;
}MyStruct cstruct_get_data_self() // 返回结构体
{return (MyStruct){"csdn",100,99};
}

python调用

from ctypes import *cLib = cdll.LoadLibrary('./cstruct.so')class MyStruct(Structure):_fields_ = [('name', c_char*10),('age', c_ubyte),('score', c_int),        ]cLib.cstruct_get_data_self.restype = MyStruct #指定函数返回值结构体本身
dat = cLib.cstruct_get_data_self() 
print("=====get struct self from .so function=======")
print("name=",dat.name)
print("age=",dat.age)
print("score=",dat.score)cLib.cstruct_get_data_pointer.restype = POINTER(MyStruct) #指定函数返回值结构体指针
dat = cLib.cstruct_get_data_pointer() 
print("=====get struct point from .so function=======")
print("name=",dat.contents.name)
print("age=",dat.contents.age)
print("score=",dat.contents.score)

运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/193685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

某音订单接口在电商行业中的重要性及实践应用

一、引言 随着移动互联网的快速发展&#xff0c;短视频平台抖音已经成为人们日常生活中不可或缺的一部分。越来越多的商家开始利用抖音平台推广和销售商品&#xff0c;从而实现商业变现。在这个过程中&#xff0c;抖音订单接口起到了至关重要的作用。本文将详细探讨抖音订单接…

希尔排序(Java)

目录 希尔排序的步骤&#xff1a; Java实现希尔排序&#xff1a; 希尔排序&#xff08;Shell Sort&#xff09;是一种插入排序的改进算法&#xff0c;它通过比较距离较远的元素交换位置&#xff0c;从而实现数据局部的较小规模排序&#xff0c;逐渐减小元素之间的间隔&#x…

遥感方向期刊总结

开眼看期刊~ 期刊分区信息搜索网址中国科学院文献情报中心期刊分区表升级版科研通期刊查询&#xff1a; 遥感领域常见期刊Nature CommunicationsRemote Sensing of EnvironmentProceedings of the National Academy of Sciences &#xff08;PNAS&#xff09;ISPRS Journal of …

C++ day50 买卖股票最佳时机

题目1&#xff1a;123 买卖股票的最佳时机Ⅲ 题目链接&#xff1a;买卖股票的最佳时机Ⅲ 对题目的理解 prices[i]表示股票在第i天的价格&#xff0c;最多可以完成两笔交易&#xff0c;不能同时进行多笔交易 可以买卖一次&#xff0c;两次&#xff0c;也可以不买卖 动态规划…

[字符串操作] 分割乘积

​ 分割乘积 题目描述 给定一个整数&#xff0c;求插入两个乘号将该整数分割成三个数之后&#xff0c;三个数的的最大乘积。 关于输入 只有一行&#xff0c;一个整数。 关于输出 所求出的最大乘积。 例子输入 4242例子输出 336提示信息 整数有正有负&#xff0c;注意&…

yolov5 7.0版本部署手机端。通过pnnx导出ncnn。

yolov5 7.0版本部署手机端。通过pnnx导出ncnn。 流程配置ncnn android yolov5导出自己模型的ncnn修改yolo.py文件导出TorchScript文件pnnx转torchscript为ncnn 安卓运行权重路径输入输出anchors 大小类别名generate_proposals方法修改 结果 流程 网络yolov5 的部署已经有很多了…

最新最全的Postman接口测试: postman实现参数化

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数…

Redis Cluster

概念 Redis Cluster采用多主多从的方式&#xff0c;支持开启多个主节点&#xff0c;每个主节点可以挂载多个从节点。 Cluster会将数据进行分片&#xff0c;将数据分散到多个主节点上&#xff0c;而每个主节点都可以对外提供读写服务。这种做法使得Redis突破了单机内存大小的限制…

2023第二届全国大学生数据分析大赛AB题代码

看大家需求量比较大&#xff0c;所以更新了一下A、B题的示例代码&#xff0c;部分截图如下 A题部分截图 B题部分截图 免费获取代码 关注威信公众号 Python风控模型与数据分析&#xff0c;回复 23年数据分析大赛代码 文末查看如何免费获取代码&#xff1b;编写不易&#xff0c;…

低效的DOM操作(js的问题)

使用 JavaScript 操作DOM&#xff08;即添加、修改和删除元素&#xff09;是相对容易&#xff0c;但操作效率却不怎么样。 比如&#xff0c;每次添加一系列DOM元素。添加一个DOM元素是一个昂贵的操作。连续添加多个DOM元素的代码是低效的。 当需要添加多个DOM元素时&#xff…

【数据结构】AOV网与拓扑排序

一.AOV网的概念&#xff08;Activity On Vertex Network&#xff09; 在一个表示工程的有向图中&#xff0c;用顶点表示活动&#xff0c;用弧表示活动之间的优先关系。这样的有向图为顶点表示活动的网&#xff0c;我们称为AOV网&#xff08;Activity On Vertex Network&#xf…

scikit-learn线性回归法进行利润预测

大家好&#xff0c;生成式人工智能无疑是一个改变游戏规则的技术&#xff0c;但对于大多数商业问题来说&#xff0c;回归和分类等传统的机器学习模型仍然是首选。 私募股权或风险投资这样的投资者利用机器学习&#xff0c;首先必须了解关注的数据以及它是如何被使用的。投资公…

anaconda 笔记:安装anaconda之后显示conda command not found

解决方法是在.bashrc文件中添加如下一行文字&#xff08;如果没有.bashrc文件&#xff0c;就在root中新建一个这个文件&#xff09; export PATH$PATH:/home/Your_name/anaconda3/bin也就是安装anaconda3的路径 然后退出编辑&#xff0c;在命令行中敲入 source ~/.bashrc即可…

云原生Kubernetes系列 | init container初始化容器的作用

云原生Kubernetes系列 | init container初始化容器的作用 kubernetes 1.3版本引入了init container初始化容器特性。主要用于在启动应用容器(app container)前来启动一个或多个初始化容器,作为应用容器的一个基础。只有init container运行正常后,app container才会正常运行…

Spring——IOC,DI,AOP

Spring框架是一个轻量级的Java开发框架&#xff0c;它提供了许多功能强大的特性来简化Java应用程序的开发。其中&#xff0c;IOC&#xff08;控制反转&#xff09;、DI&#xff08;依赖注入&#xff09;和AOP&#xff08;面向切面编程&#xff09;是Spring框架的三大核心特性。…

k8s安装学习环境

目录 环境准备 配置hosts 关闭防火墙 关闭交换分区 调整swappiness参数 关闭setlinux Ipv4转发 时钟同步 安装Docker 配置Yum源 安装 配置 启动 日志 安装k8s 配置Yum源 Master节点 安装 初始化 配置kubectl 部署CNI网络插件 Node节点 检查 环境准备 准…

同步代码,异步代码-微任务 宏任务 事件循环(输出题)

1.知识点 事件循环&#xff1a; 由浏览器Web API管理的异步代码&#xff0c;如果有结果后&#xff0c;会根据这个异步代码的类型&#xff0c;被放入对应的微任务或宏任务当中。当执行栈的任务&#xff08;同步代码&#xff09;全部执行完毕后&#xff0c;再执行完所有微任务的…

springboot(ssm 二手图书交易系统 图书销售系统Java(codeLW)

springboot(ssm 二手图书交易系统 图书销售系统Java(code&LW) 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&#…

Google Guava 缓存工具使用详解

文章目录 缓存工具Cache接口LoadingCache接口CacheBuilder类CacheLoader类CacheStats类RemovalListener类 缓存工具 Guava提供了Cache接口和相关的类来支持缓存功能&#xff0c;它提供了高性能、线程安全的内存缓存&#xff0c;可以用于优化应用程序的性能。 特点&#xff1a…

Flutter 控件查阅清单

为了方便记录和使用Flutter中的各种控件&#xff0c;特写此博客以记之&#xff0c;好记性不如烂笔头嘛&#xff1a;&#xff09; 通过控件的首字母进行查找&#xff0c;本文会持续更新 控件目录 AAppBar BCContainerColumn &#xff08;列&#xff09; DDivider (分割线) EElev…