Python调用C语言

本文介绍了如何在Python中使用ctypes调用C函数,以及在Windows环境下创建C++动态链接库的详细步骤,包括头文件编写、编译和链接过程。
摘要由CSDN通过智能技术生成

事实证明,用Python有时确实不如C语言来的快,现在考虑将两者混编的问题。参考网上的东西,做点笔记:

1.How to Call a C Function in Python
(1)Using the ctypes Library
Python ctypes库是一个强大的资源,它使我们能够生成与C兼容的数据类型,并使用Python直接调用动态链接库或共享库中的函数。下面,你将找到一个全面的演练,详细介绍如何利用ctypes调用C函数:

步骤一:引入库

import ctypes

步骤二:加载包括C函数的共享库

lib = ctypes.CDLL('./mylibrary.so')

这一步将共享库文件加载到存储器中,使得其中的函数能够被访问

步骤三:声明函数原型

my_function = lib.my_function
my_function.argtypes = [ctypes.c_int, ctypes.c_int]
my_function.restype = ctypes.c_int

在这一步,通过将库中的C函数和Python变量联系起来,我们建立了函数原型。而且,我们使用argtypes定义参数类型和使用restype定义返回类型。

步骤四:从Python调用C函数

result = my_function(5, 10)
print(result)

最后,我们就像调用其他任何Python函数一样调用C函数。传入所需的参数,它将执行相应的C代码。执行结果将被存储在变量中。

那么问题来了,如果我在Windows中实施混编,该怎么建立C语言的动态连接库或共享库?
读读这个吧:How to Create C/C++ Dynamic-link Libraries in Windows

将程序模块化为单独的组件,以简化部署和安装

根据微软官方,dll文件是:

包含代码和数据的库,这些代码和数据可以同时被多个程序使用。这有助于促进代码重用和有效的内存使用。
通过使用dll,一个程序可以被模块化成独立的组件,每一个模块可以在运行时间被加载到主程序中,如果那个模块被安装了。因为模块是分开的,所以程序的加载时间更快,并且只有在请求该功能时才加载模块。

在Windows平台上,共享库被称为动态链接库(.dll)。而在其他平台中则被表示为.so扩展的共享对象。

1.在根目录上开3个头文件
(1)include —— 为了存储头文件。在如何与编译的共享库交互的问题上,头文件将被用于应用。如果其他开发者希望使用你的共享库去开发他们自己的程序,头文件就是必不可少的。
(2)obj —— 为了在编译期间存储所创造的临时obj文件,你可以安全的删掉这些文件。
(3)src —— 为了存储你的功能的必备代码。在部署期间,你将从包中排除这些文件。对使用你的程序的用户只提供共享库和可执行文件。

2.写头文件add.h
这个头文件要写在上述文件夹中的include文件夹,内容为:

#ifndef _ADD_H
#define _ADD_H
extern "C"
{
    __declspec(dllexport) int add(int, int);
    __declspec(dllexport) int sub(int, int);
    __declspec(dllexport) int mul(int, int);
}
#endif

如果用C来写,就不需要extern和delspec(dllexport)

3.执行代码
现在转移到src文件夹创造新文件add.cpp:

#include "add.h"
extern "C"
{
    __declspec(dllexport) int add(int a, int b) 
    {
        return a + b;
    }
    __declspec(dllexport) int sub(int a, int b)
    {
        return a - b;
    }
    __declspec(dllexport) int mul(int a, int b)
    {
        return a * b;
    }
}

4.返回根目录创造主文件main.cpp:

#include <iostream>
#include "add.h"

int main()
{
	std::cout << add(2, 2) << "|" << sub(3, 1) << "|" << mul(3, 3) << std::endl;
	return 0;
}

5.对象文件:
Visual Studio向我们提供了他们自己的开发者命令提示符,这允许我们编译可执行文件。我们能在Visual Studio的目录上找到Native Tools Command Prompt for VS。比如这样:
在这里插入图片描述
现在要让它指向之前的main.cpp所在的目录,刚刚发现转移目录转不动,参考这篇就好了Change directory in visual studio command prompt。其实就是cd /d 后面带上去的目录就行。
输入命令:

cl /EHsc /c .\src\*.cpp /I .\include /Fo".\obj\\"

执行结果:
在这里插入图片描述
这条命令中有几个符号要注意:
(1) /c —— 源代码文件的位置,使用*去包含所有在src文件夹中的cpp文件。
(2) /I —— 头文件的位置,默认将包含.h扩展的文件。
(3) /Fo —— 将要在编译期间被创造的临时obj文件的位置,请注意在/Fo的后面不要留空。
现在你就会发现,在文件夹obj里多了一个叫add.obj的文件。

6.链接.obj文件并创建一个共享库
运行下面的命令

link /DLL /OUT:add.dll .\obj\*.obj

之后多出了这3个文件
(1)add.dll —— 你的程序的共享库,你的可执行文件需要它来运行相关的函数。
(2)add.exp —— 这个文件是可以安全的删除的。
(3)add.lib —— 编译期间所需的静态库,用来制作可执行文件

7.可执行文件
最后就是创造可执行文件了,运行下面的指令:

cl /EHsc main.cpp /Fetest.exe /I .\include /link *.lib

我们将使用.lib文件而不是.dll文件,因为编译需要静态库,而动态链接库用于编译后运行可执行文件。运行结果:
在这里插入图片描述
在根文件夹中,有可直接运行的文件test.exe.
您可以简单地部署以下文件以供使用。确保test.exe和add.dll两者位于同一目录中。

注意: 博文How to Create C/C++ Dynamic-link Libraries in Windows所描述的方法可能只适合写成C++的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值