python一个非常的大的优点就是开发效率高,非常不好的缺点就是执行效率低;然而c语言有个则刚好相反。还有一点python的对源码的保护做不到,即使你用py2exe,pyinstaller这样的方法也是很容易被反编译出来。但是c写的代码反编译的难度就极大地增加。所以如果你写的代码里面如果包含了一些敏感的东西,那么你可以把这段代码使用c来写。

那么我们是不是可以结合起来使用呢?

答案是完全可以,用c来写一个动态库/共享库,然后在python中调用。

python 的解释器本身就是用c写的,所以调用c是很方便的,调用的方法不止一种,我们这里介绍使用ctypes这种方式。

我们会写一个测试代码来演示怎么在python中调用c函数,包括python传整型和字符串参数给c库,c库中返回整型和字符串。这个测试将在windows xp平台+python2.7实施。

接下来我们把要做的事情分成2个阶段,用c编写一个动态库,在python中调用这个动态库。

c编写一个动态库

使用vc6创建一个空的win32动态库,添加2个文件

testcdll.c

tsetcdll.def

testcdll.c的内容如下:

#include

#include

int add( int a, int b )

{

return a + b;

}

char* pStr = 0;

int nMax = 128;

char* makestring( )

{

pStr = ( char* )malloc(nMax);

memset( pStr, 0, nMax );

strcpy( pStr, "test is test string" );

return pStr;

}

void delstring( void )

{

if ( 0 != pStr )

{

free( pStr );

pStr = 0;

}

}

char* catstring( char* pinput )

{

if ( 0 == pinput )

{

return 0;

}

if ( 0 == pStr )

{

pStr = ( char* )malloc(nMax);

}

memset( pStr, 0, nMax );

strcpy( pStr, "test is test string--" );

strcat( pStr, pinput );

return pStr;

}

然后编译,得到后面测试要用到的testcdll.dll

如果你不想用IDE的话, 你可以直接使用命令行来编译:

cl /LD testcdll.c tsetcdll.def  /link /out:testcdll.dll

调用这个动态库

因为我们的测试比较简单所以我们就不写源码文件,直接在解释器中写测试代码了。

打开命令行cmd,cd到刚才我们生成dll的文件夹,执行python

到解释器界面,依次执行下面的命令:

>>> from ctypes import *

>>> hd = cdll.LoadLibrary('FoxLicenseMgr.dll')

>>> hd.add( 2, 3 )

5

>>> hd.makestring.restype = c_char_p

>>> hd.makestring()

'test is test string'

>>> hd.delstring()

1

>>> s1 = 'python'

>>> cs1 = c_char_p( s1 )

>>> hd.catstring(cs1)

12068640

>>> hd.catstring.restype = c_char_p

>>> hd.catstring(cs1)

'test is test string--python'

>>> dir(hd)

['_FuncPtr', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '_

_getattr__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__modul

e__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__si

zeof__', '__str__', '__subclasshook__', '__weakref__', '_func_flags_', '_func_re

stype_', '_handle', '_name', 'catstring', 'delstring', 'makestring']

>>> exit()

对上面语句稍作解释,

from ctypes import *

因为我们使用的是ctypes的这种方式,需要导入ctypes。

hd = cdll.LoadLibrary('testcdll.dll')

加载我们之前生成的动态库,因为我们已经cd到testcdll.dll所在的目录所以不用加全路径,否则你需要写全路径的。

hd.add( 2, 3 )

直接调用add函数,传进2个参数,参数不需要额外的转换,直接传进去,有些类型是不可以直接传的,需要做个转换,这个后面会提到。调用这一句后,就直接输入结果到控制台上结果为5

调用返回为字符串的函数的时候,需要设置返回类型,否则就会返回一整型值,这是python调用c函数的默认的返回值,如上面调用catstring的之前没有设置返回值,结果返回一个数值

>>> hd.catstring(cs1)

12068640

设置返回类型使用下面的语法:

hd.makestring.restype = c_char_p

因为我们的返回类型是char*, 所以使用c_char_p,这个和char*是对应的。其他的python的ctypes的类型和c类型的映射关系如下:

ctypes type

C type

Python type

_Bool

bool (1)

char

1-character string

wchar_t

1-character unicode string

char

int/long

unsigned

char

int/long

short

int/long

unsigned

short

int/long

int

int/long

unsigned

int

int/long

long

int/long

unsigned

long

int/long

__int64 orlonglong

int/long

unsigned

__int64 orunsignedlonglong

int/long

float

float

double

float

long

double

float

char

* (NUL terminated)

string or None

wchar_t

* (NUL terminated)

unicode or None

void

*

int/long or None

调用makestring()来返回一个字符串:

>>> hd.makestring()

'test is test string'

如果传入的是字符串,也需要做一个转换

>>> s1 = 'python'

>>> cs1 = c_char_p( s1 )

然后再传入,因为这个函数的返回的是字符串因此也需要设置返回类型:

>>> hd.catstring.restype = c_char_p

>>> hd.catstring(cs1)

'test is test string--python'

最后使用dir来查看这个hd的都有那些可用的方法。

完。

版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则按侵权处理.

分享到:

python调用c的配置文件_python调用c相关推荐

  1. python调用webservice接口实例_python调用各种接口,webservice,c接口,com接口,socket协议方法...

    python调用webservice接口(SOAP) (2)调用示例: 需要先安装suds库:pip install suds from suds.client import Client #如果需要 ...

  2. python 接口测试 如何写配置文件_python接口自动化测试 - configparser配置文件解析器详细使用...

    configparser简介 ConfigParser模块已在Python 3中重命名为configparser 该模块定义了ConfigParser类. ConfigParser类实现一种基本的配置 ...

  3. python 调用 c 生成数组_python调用c++传递数组的实例

    如下所示: input = c_int * 4 # 实例化一个长度为2的整型数组 input = input() # 为数组赋值(input这个数组是不支持迭代的) input[0] = 11 inp ...

  4. python调用离线百度语音识别_python调用百度语音识别api

    最近在处理语音检索相关的事. 其中用到语音识别,调用的是讯飞与百度的api,前者使用js是实现,后者用python3实现(因为自己使用python) 环境: python3.5 centos 7 流程 ...

  5. python调用c++动态库_Python调用C/C++动态链接库的方法

    本文以实例讲解了Python调用C/C++ DLL动态链接库的方法,具体示例如下: 示例一: 首先,在创建一个DLL工程(本例创建环境为VS 2005),头文件: //hello.h #ifdef E ...

  6. python调用c#注意事项_Python调用C#编写的DLL

    起因是工作中需要用的开发编写的DLL,但是它是使用C#编写的,本人不想使用C#去写测试代码,所以需要使用Python来掉这个DLL内的方法 就用这个就很好,不要问为啥不用微软的Ironpython和别 ...

  7. python调用webservice接口实例_python调用webservice接口的实现

    使用suds这个第三方模块 from suds.client import Client url = 'http://ip:port/?wsdl' cilent=Client(url) print c ...

  8. python调用.a静态库_Python 调用 C

    了解了相关资料 不折腾的方法有(以往文章有): pypy,numba,numpy 但都不是 纯正的 C 折腾的: cffi,Cython,Boost.Python,Cpython 自带模块,SWIG ...

  9. python调用cmd执行命令_python调用命令行,其中包含“echo”和“|”

    参见英文答案 > piping in shell via Python subprocess module 4个 我试着用python调用命令行执行一些文件.但是,当有一个包含"ech ...

最新文章

  1. filter---用angularjs实现关键字高亮
  2. python科学计算模块有什么_Python科学计算—numpy模块总结(1)
  3. html文件 运行php文件路径问题,HTML_基础 HTML之目录问题(相对路径和绝对路径区别),相对路径-以引用文件之网页所 - phpStudy...
  4. QT的QSharedDataPointer类的使用
  5. 【问题解决】无法创建新的堆栈防护页面
  6. java禁止修改map_Java中实现不可变Map
  7. [HDOJ1897]继续畅通工程
  8. UVA545 LA5263 Heads【对数】
  9. 第三章(jQuery中的DOM操作)
  10. MPLS virtual private network PE-CE之间的路由协议(BGP)
  11. MybatisPlus常用条件查询器Wrapper的使用
  12. Java Base64与图片互转操作测试
  13. windows server 12 r2用Hyper-v安装centos7
  14. PDE——delta函数
  15. Android Studio初学者实例:Fragment学习--仿美团外卖界面
  16. java计算机毕业设计web家庭财务管理系统MyBatis+系统+LW文档+源码+调试部署
  17. excel中多列内容显示不全
  18. 【Adrealm智库专栏】数字广告为何需要“去中心化”?
  19. 小萌库- 新海诚那些唯美感人的动漫
  20. Windows Installer问题集结及解决办法

热门文章

  1. 新手WEB开发者易出现的30个问题(转)
  2. QT中使用OpenGL绘制图形
  3. MFC的Main函数跑哪去了
  4. 怎么给自己的python换源_windows/linux下如何更换Python的pip源
  5. 树莓派通过VNC连接时分辨率太低
  6. c语言用数组实现栈的插入,用数组实现栈的功能的C语言代码?
  7. 打开输入花里胡哨的特殊符号
  8. 4字节 经纬度_Swift4 经纬度计算日出日落时间
  9. mnist手写数字识别python_基于tensorflow的MNIST手写数字识别(二)--入门篇
  10. es6 数组合并_对比 ES5,学习 ES6(一)