您的位置:首页 > 编程语言 > C语言/C++

Python调用C语言代码

2013-08-12 17:11 513 查看
python调用C语言写的代码,其实是调用C代码生成的动态链接库(.dll文件)里的二进制代码。

PS:其实,说到底,无论你用什么语言编写程序,计算机最后执行的都是二进制的机器代码。故可用这种方式实现任意两种语言间的相互调用(关键是要可生产二进制文件哦)。

首先,我们来看看如何生成dll动态链接库文件。

1、在VS中  【创建】【Win32 控制台项目 】 --> 输入项目名称【myDll】--> 接下来选择【dll】和【空项目】 -->点击确定

2、添加cpp文件,命名为myDll.cpp,

我们要编写一个名为做整形加法的函数名为add

和一个做整形减法的函数,名为sub

编写代码如下:

//_declspec(dllexport) 将要导出到dll文件中的函数
_declspec(dllexport) int add(int a,int b)
{
return a+b;
}

_declspec(dllexport) int sub(int a,int b)
{
return a-b;
}
3、点击菜单栏【生成】 --> 【生成myDll】,之后找到工程目录下的Debug文件夹,找到生成的myDll.dll和myDll.lib文件。接下来我们可以用dumpbin命令测试myDll.dll文件中包含的函数。将myDll.dll文件拷贝到C盘根目录,打开cmd进入C盘根目录输入命令:

dumpbin -exports myDll.dll

如果cmd中出现有如下两行,表示add函数和sub函数成功导入dll文件。没有用过dumpbin工具的,请去网上搜索dumpbin,资料很多,也很容易用,在此不再多叙述了。

 1    0 000112A8 ?add@@YAHHH@Z

 2    1 00011663 ?sub@@YAHHH@Z

第一行和第二行中分别显示有add和sub函数,表示两个函数成功导入到dll库。

测试完再删除C盘里的myDll.dll文件。

我们先看看C语言是怎么调用C语言生成的dll文件的。

1、我们【创建】【Win32 控制台程序】 --> 选择【空白项目】

2、添加新项 【dllTest.cpp】,编写代码如下:

#include "stdio.h"

_declspec(dllimport) int add(int a,int b);

_declspec(dllimport) int sub(int a,int b);

int main()

{
int a=5;
int b=4;
printf("%d + %d = %d\n",a,b,add(a,b));
printf("%d - %d = %d\n",a,b,sub(a,b));
return 0;

}

3、好了,我们来生成解决方案,但是返现有如下报错:

dllTest error LNK2019: 无法解析的外部符号 "__declspec(dllimport) int __cdecl sub(int,int)" (__imp_?sub@@YAHHH@Z) ,该符号在函数 _main 中被引用

dllTest error LNK2019: 无法解析的外部符号 "__declspec(dllimport) int __cdecl add(int,int)" (__imp_?add@@YAHHH@Z) ,该符号在函数 _main 中被引用

dllTest fatal error LNK1120: 2 个无法解析的外部命令

这是因为我们的编译器找不到包含我们编写的add和sub函数,我们将myDll.lib文件复制到工程文件目录下,将myDll.dll文件复制到工程文件下的Debug目录中。另外我们得显示得指示编译器应该从lib文件导入函数,因此我们得到菜单栏【项目】-->【属性】-->【链接器】-->【输入】-->【附加依赖库】中添加我们的mydll.dl库文件文件。再次编译,l发现没有问题,运行之后结果如下:

5 + 4 = 9

5 - 4 = 1

Press any key to continue

 
好了,接下来我们进入Python单元,下面讲述怎么在python中调用我们编写的add和sub函数

1、新建myDllTest.py文件,编写代码如下:

from ctypes import *

print 'import ctypes OK'

dll = CDLL("myDll.dll")

print 'init dll ok'

print dll.add(5,4)

print dll.sub(5,4)

2、同样的,为了让解释器找到add和sub函数,我们将上面生成的myDll.dll放到myDllTest.py文件的文件夹下,因为myDllTest.py在运行时会默认在本文件目录下寻找myDll.dll文件

3、然后运行程序: myDllTest.py

结果发现程序运行显示import ctypes OK和init dll ok,表明前四句话执行没有问题,然后提示说找不到我们需要的add函数:

import ctypes OK

init dll ok

Traceback (most recent call last):

……

AttributeError: function 'add' not found

原因是在python中调用C语言写的代码时,要在C语言源码模块中加上extern "C"声明,表示本段代码是用C语言源代码生成的,不然用别的语言调用时会发生找不到代码的情况。

故我们再打开我们的myDl.l动态链接库工程,将myDll.cpp的代码改为:

extern "C"

{
_declspec(dllexport) int add(int a,int b)
{
return a+b;
}

_declspec(dllexport) int sub(int a,int b)
{
return a-b;
}

}

再次生成dll文件,考到myDllTest.py所在文件夹下,再次运行,

得到运行结果如下:

import ctypes OK

init dll ok

9

1

至此,我们可以看到我们编写的函数成功地得到调用,是不是很简单呢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息