0

0

python与C互相调用的详细介绍

零下一度

零下一度

发布时间:2017-07-16 12:03:48

|

2076人浏览过

|

来源于php中文网

原创

 虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中一些模块的实现方式,后者服务端程序(实现业务扩展或是plugin功能)和游戏开发(脚本只处理逻辑)中比较常见。本文主要介绍通过在c中运行python脚本来实现python与c的相互调用,并通过c和python脚本设置同一段内存区域为例子来讲解。

前言

最近因为工作的需要,在考虑基于udp做一个用于网游战斗中的数据同步协议,为了前期测试数据,决定先做一个外部的代理tunnel,原理是在server端和client端分别建立网络转发proxy,即原来的C/S连接改为两个proxy之间数据快速传输。因为udp库是用C++写的代码,在测试数据的时候需要不断地修改参数,重新编译,修改输出统计数据制表等,不胜其烦,最终决定导出接口由python脚本来进行逻辑调用。下面话不多说,来一起看看详细的介绍:

准备工作

  为了在c中运行python脚本,需要在程序链接的时候将python虚拟机库链接进去,python虚拟机库是python安装目录下libs中的python27.lib文件,至于怎样将库链接进程序中可以自己google下。由于在c中使用了python的一些方法和数据结构,所以需要将python安装目录下的include目录添加到项目include目录中。好了,需要准备的就是这些,然后就可以开始实现一个设置内存区域的例子了。

立即学习Python免费学习笔记(深入)”;

C/C++导出到python有多种方法,根据不同的需求,可以使用下面不同的方式:

1、ctypes绑定。ctypes就包含在万能的python标准库模块里面,它可以运行时载入动态链接库(dll,so),在CPython 2.x/3.x和PyPy上都支持。这种方式好处就是不用针对性地用python api写导出函数,可以直接加载动态链接库的符号表,在python中就可以直接调用了。

2、第三方的python binding。例子有boost-python,实现方式是工具自动化用Python/C api生成一系列C++ wrapper函数。特别适用于大型的库或引擎导出到python。

3、手动写python binding函数。如果对Python C api熟悉的话,这种方式应该是最灵活的,读一遍API文档就可以使用。理论上效率应该是最好的,但对于我这种python初学者,可能需要花上不少时间。

六七企业网站管理系统(67CMS)2.0
六七企业网站管理系统(67CMS)2.0

经过一年的开发更新与升级,67CMS2.0版正式上线67cms 2.0的变革1.不再需要授权,商业用户免费使用!!2.栏目分类的级别添加至四级3.单页的级别添加至四级4.新增加人才招聘模块,招聘也可进行分类检索,采用公用的分类调用5.图集采用新的js效果调用6.英文版后台已翻译完毕,可无限添加语言包7.其他N多细节修改,与Bug修复不做详细介绍了

下载

以之前折腾C函数导出到Lua脚本的经历,本以为要先研究一番python c api,再搞上半天才能搞定。后面发现python标准库模块的ctypes已经非常强大,虽然性能应该是三种方式里面最差的,但在这个最高60fps的tunnel里面,C/Python接口边界调用的损耗先忽略。跟其他两种方式设计不一样的是,ctypes采用的是非入侵式调用接口的方式,不需要修改原来的C接口或者写一些绑定代码,直接对编译出来的动态库进行调用。ctypes使用过程也是非常愉悦的。

下面介绍下ctypes的使用:

1、加载DLL动态链接库

这里需要注意区分动态链接库函数是使用cdecl还是stdcall的调用约定,分别使用cdll或windll加载动态库。

例如:

# 加载udp库函数 
udp_server = cdll.LoadLibrary("./udp_server.so") 
init_udp_server = udp_server.init_udp_server 
destroy_udp_server = udp_server.destroy_udp_server 
update_udp_server = udp_server.update_udp_server 
SendMsg = udp_server.SendMsg 

SetConnectCallback = udp_server.SetConnectCallback 
SetDisconnectCallback = udp_server.SetDisconnectCallback 
SetTimeoutCallback = udp_server.SetTimeoutCallback 
SetRecvCallback = udp_server.SetRecvCallback

2、数据类型映射

除了ctypes定义的基本数据类型(c_char, c_int, c_double等),还能使用pointer函数转换成指针类型。对于要导出的网络库,设置回调函数是必不可少的,在C++库里面,回调函数是通过设置一个函数指针完成的,ctypes同样支持函数指针的声明。如:recv_cb = CFUNCTYPE( None, c_char_p, c_int ) ,表示一个返回值为void,参数为char*和int类型的回调函数。


def init(self, port, ip="127.0.0.1"): 
  self._port = port 
  self._ip = ip 

  self._clients = {} 

  self.c_connect_cb = connect_cb(self.server_connect) 
  self.c_disconnect_cb = disconnect_cb(self.server_disconnect) 
  self.c_timeout_cb = timeout_cb(self.server_timeout) 
  self.c_recv_cb = recv_cb(self.server_recv) 

def create(self): 
  if self._port: 
   if init_udp_server(self._ip, self._port) == 0: 
    print "server listen %s:%d" % (self._ip, self._port) 
    SetConnectCallback( self.c_connect_cb ) 
    SetDisconnectCallback( self.c_disconnect_cb ) 
    SetTimeoutCallback( self.c_timeout_cb ) 
    SetRecvCallback( self.c_recv_cb ) 
    return True 
  print "[error] init_udp_server error", self._ip, self._port 
  return False

绑定回调参数需要注意的是,绑定的回调函数需要保存为成员变量(上面的写法),目的是避免python垃圾回收导致回调函数变成野指针。这算是一个小小的坑吧。基本上一个小小的库也就用到这些功能。

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号