IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Python调用C/C++动态链接库 -> 正文阅读

[C++知识库]Python调用C/C++动态链接库

最近需要使用Python调用C/C++功能,于是进行了一些相关调研。总体来说,Python调用C功能还算是相对比较简单,主要涉及ctypes这个函数库。

ctypes?是 Python 的外部函数库。它提供了与 C 兼容的数据类型,并允许调用C共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。

基本数据类型的使用

ctypes定义了一些与C兼容的数据类型:

本篇主要关注跨语言调用时指针的处理方法,对于更全面的介绍,可参考:ctypes --- Python 的外部函数库 — Python 3.7.13 文档

下面用一个小例子来介绍Python调用C/C++动态库的方法。

C代码:

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

#ifdef __cplusplus
extern "C"
{
#endif

using namespace std;

// test for input char pointer
void print_string(char* str)
{
    printf("This is c code: print_string().\n");
    printf("%s\n", str);
}

// test for input integers and return an integer
int add_func(int a, int b)
{
    printf("This is c code: add_func()\n");
    return a + b;
}

// test for pointer as return value
int* get_array()
{
    int *pa = new int[10];
	for(int i = 0; i < 10; i++)
	{
			pa[i] = i;
	}
	return pa;
}

void free_array(int *pa)
{
	if(pa)
		delete [] pa;

}

#ifdef __cplusplus
}
#endif

上面测试代码定义了普通整数的计算并返回整数、输入字符指针并打印、输出整型指针、释放指针等操作。需要注意的是,由于ctypes只与C兼容,而C++因为支持函数重载而在编译时修改函数名,因此,对于C++代码,需要使用C的方式编译。不了解的同学可自行搜索extern "C"的用法,本篇不做过多展开。

将以上代码编译成动态链接库:

g++ -std=c++11 test_c.c -shared -fPIC -o test_c.so

接着,我们使用Python来调用该动态库。Python代码:

#!/usr/bin/python

from ctypes import *
import os

# Load dynamic library
#lib_path = os.getcwd() + '/test_c.so'
lib_path = './test_c.so'
solib = cdll.LoadLibrary(lib_path)

# Indicate the function arguments type and return value type
solib.print_string.argtypes = [c_char_p]
solib.print_string.restype = c_void_p

# Call print_string function in C library
solib.print_string(b"Hello Python!")

# Call add function in C library
solib.add_func.argtypes = [c_int, c_int]
solib.add_func.restype = c_int
sum = solib.add_func(100,200)
print('Python code: sum = {}'.format(sum))


# Call get_array function in C library, the return value is a pointer of integer
solib.get_array.restype = POINTER(c_int)
p_array = solib.get_array()
int_array = [p_array[i] for i in range(10)]

print("Python code: ")
for x in int_array:
    print(x, end = ' ')

# Free the pointer
solib.free_array.argtypes = [POINTER(c_int)]
solib.free_array.restype = c_void_p
solib.free_array(p_array)

print('\nEnd Python')

运行结果:

在Python代码调用C动态库时,C库函数的参数和返回值必须是ctypes类型,参数类型使用关键字argtypes定义,对参数的定义必须是以序列的形式,如上面代码中的参数类型定义:

solib.add_func.argtypes = [c_int, c_int]

solib.print_string.argtypes = [c_char_p]

返回值参数类型使用restype定义,如上面代码中的语句:

solib.add_func.restype = c_int

solib.get_array.restype = POINTER(c_int)

其中,get_array函数的返回值使用POINTER(c_int)关键字定义成了int型的指针。

用户自定义类型的使用

除了基本数据类型,用户还可以使用自定义类型,下面给出一个自定义结构体的测试例子:

C代码:

typedef struct _point
{
        int x;
        int y;
        char desc[50];
}Point;

int get_point(Point point)
{
        printf("x = %d, y = %d, desc = %s\n", point.x, point.y, point.desc);
        return 0;
}

Python代码:

class Point(Structure):
        _fields_ = [
                ("x", c_int),
                ("y", c_int),
                ("desc", c_char * 50)
        ]


pt = Point(5, 10, b'I am a point.')
print(pt.x, pt.y, pt.desc)

solib.get_point.argtypes = [Point]
solib.get_point.restype = c_int


solib.get_point(pt)

Python中定义结构体时,必须继承Structure类,其成员的定义必须使用_fields_属性,否则无法调用C结构体。_fields_属性是一个list,其成员均为2个值的tuple,分别对应结构体成员的名称(C结构体成员名称)和类型,类型为ctypes类型,或者是由ctypes组合而成的新类型(如自己定义的结构体)。

以上代码的运行结果:

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 18:34:21  更:2022-07-20 18:35:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 0:58:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码