Python调用C语言(DLL)

Posted 王张飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python调用C语言(DLL)相关的知识,希望对你有一定的参考价值。

前言:本文可结合Python调用C++语言(DLL)使用,效果更佳。

采用导出形式:__declspec(dllexport) 
功能
无参数,无返回类型
有参数,有返回值 【不需要修改参数数值】
有参数  【需要修改参数数值,使用指针】
有参数【传数组,也使用指针】
有返回值为数组【传数组,也使用指针】
调用其他函数

Python调用C语言的三个步骤

1)编写C语言函数代码
2)将C代码转换成动态库(Windows下为.dll,Linux下为.so)
3)利用Python自带库(ctypes)调用步骤2中生成的库文件

本文文件的代码请参考文末下载链接

使用Visual Studio软件将C程序编译为DLL

首先创建test01.c

#include<stdio.h>
#include<malloc.h>

//无参数,无返回类型
__declspec(dllexport) void __stdcall hello()

	printf("Hello,NEU!\\n");


//有参数,有返回值
//不需要修改参数数值
__declspec(dllexport) int __stdcall add(int a, int b)

	return a + b;


//有参数
//需要修改参数数值,使用指针
__declspec(dllexport) void __stdcall inc(int *a)

	(*a)++;


//有参数
//传数组,也使用指针
__declspec(dllexport) void __stdcall printArr(int *a, int n)

	int i;
	for (i = 0; i < n; i++)
	
		printf("%d ", *a++);
	


//有返回值为数组
//传数组,也使用指针
__declspec(dllexport) int* __stdcall getArr()

	int *p, *q;
	q = p = (int*)malloc(sizeof(int) * 4);
	int i;
	for (i = 0; i < 4; i++)
	
		*p++ = i;
	
	return q;


//调用其他函数
void heiheihei()

	printf("Hello,NEU!!!!");

__declspec(dllexport) void __stdcall callFunc()

	heiheihei();

接下来配置VS,首先选择属性

因为我们生成的是DLL,所以讲配置类型从exe更改为DLL

开始进行调试,注意我们使用的Python是64位的,所以这里选择64位编译

编译之后如果提示如下所示错误,不用担心,因为我们生成的DLL不是可执行文件。

下面我们去寻找生成的DLL文件


返回上一层,在\\ConsoleApplication1\\x64\\Release文件中可以找到DLL

下面使我们本节的重点,通过Python调用DLL

首先创建Py2C.py文件

from ctypes import *

def test01():
    ll = cdll.LoadLibrary   
    lib = ll("test01.dll")   
    lib.hello()
    
def test02():
    ll = cdll.LoadLibrary   
    lib = ll("test01.dll")   
    c = lib.add(1,2)
    print(c)
    
def test03():
    ll = cdll.LoadLibrary   
    lib = ll("test01.dll")  
    a = (c_int)(2)
    a_p = POINTER(c_int)(a)
    lib.inc(a_p)
    print(a_p[0])
    print(a.value)
    
def test04():
    ll = cdll.LoadLibrary   
    lib = ll("test01.dll")
    arr = [1,2,3,4]
    a = (c_int*len(arr))(*arr)
    a_p = POINTER(c_int)(a)
    lib.printArr(a_p,4)

def test05():
    ll = cdll.LoadLibrary   
    lib = ll("test01.dll")
    lib.getArr.restype  = POINTER(c_int) #设置返回值类型为 int*
    a = lib.getArr()
    for i in range(0,4):
        print(a[i])

def test06():
    ll = cdll.LoadLibrary   
    lib = ll("test01.dll")   
    #__declspec(dllexport)    将一个函数声名为导出函数,就是说这个函数要被包含她的程序之外的程序调用。
    lib.callFunc()


if __name__ == '__main__':
    test05()

我们复制刚刚生成的ConsoleApplication1.dll和刚刚创建的Py2C.py到同一目录下,然后运行:

python Py2C.py

这里直接运行,此时Py2C.py文件中测试的是 test05(),如下所示:

if __name__ == '__main__':
    test05()

运行之后输出结果为

Python调用C语言(DLL)下载地址


参考资料:

Python调用C语言(DLL)
Python调用C++语言(DLL)
Ubuntu下Python与C/C++混合编程(简单调用)
哔哩哔哩视频:Python和C混合编程
关于python调用C++所形成的dll文件中的以指针为返回值的函数
Python–ctypes(数据类型详细踩坑指南)

以上是关于Python调用C语言(DLL)的主要内容,如果未能解决你的问题,请参考以下文章

Python调用C++语言(DLL)

Python调用C++语言(DLL)

C语言函数(函数的分类,参数,调用,声名及定义)

Windows下如何在python中调用c语言程序编译的dll

用C语言写的API运行的时候总是先弹出一个命令行窗口,如何让他不弹出来?

EXE执行文件如何调用DLL?