C/C++开发python扩展

1 引言

有两种常见方式用于实现python调用C/C++,其一为开发动态链接库(DLL),这种通过动态链接库的方式在python中不能直接通过import导入模块,其二则为开发python扩展pyd,这种可以直接import。但两者都需要相同的配置环境,VS(2017或更新的版本,笔者用的是2017),当然python肯定是必不可少的,这个笔者用的是3.7版本的。

2 动态链接库(DLL)

2.1 开发DLL

在VS安装了C++开发组件后,就可以直接创建DLL项目,
在这里插入图片描述
在dllmain.cpp中加入下面的代码,

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

#define EXPORT __declspec(dllexport)
using namespace std;

class Test {
public: int Hello();
};

int Test::Hello() {
	int a = 45;
	return a;
}

extern "C" {
	Test t;
	EXPORT float A() {
		float c = t.Hello();
		return c;
	}
}

然后右键解决方案资源管理器中的项目名,点击生成就可以生成DLL库。在这一步之前还有重要的一点是,如果你的计算机是64位的,解决方案平台设置为x64
在这里插入图片描述
否则生成的DLL库在你的计算机上是无法使用的。

2.2 测试

生成的DLL库可以在(项目目录)\Dll1\x64\Debug这个路径下找到,下面写一段python的测试代码进行验证。

import ctypes
lib = ctypes.cdll.LoadLibrary("Dll1.dll") 
print("a", lib.A())

测试结果

a 45

3 python扩展

通过VS有两种途径用于开发python扩展,其一是直接新建C++空项目,通过设置项目属性的方式,最后生成pyd文件;其二是直接新建Python扩展模块项目。两者本质是一样的,但是第一种更容易让读者明白其中的过程。

3.1 通过C++空项目

首先新建一个空项目,
在这里插入图片描述
然后右键项目名->添加->新建项,新建一个cpp文件,命名为module1.cpp,
在这里插入图片描述
再次右键项目名->属性,在项目属性页面中,首先将配置设置为所有配置,64位的计算机则将平台设置为x64,然后按照下表的方式修改属性。
在这里插入图片描述
有几项是特别重要的,例如加入python的include和libs目录等,必须要进行设置,设置后大致如下,
在这里插入图片描述
保存设置,在module1.cpp中加入下面示例代码,

#include <Windows.h>
#include <cmath>
#include <Python.h>

const double e = 2.7182818284590452353602874713527;

double sinh_impl(double x) {
	return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
}

double cosh_impl(double x) {
	return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
}

double tanh_impl(double x) {
	return sinh_impl(x) / cosh_impl(x);
}

PyObject* tanh_impl(PyObject *, PyObject* o) {
	double x = PyFloat_AsDouble(o);
	double tanh_x = sinh_impl(x) / cosh_impl(x);
	return PyFloat_FromDouble(tanh_x);
}

static PyMethodDef superfastcode_methods[] = {
	// The first property is the name exposed to Python, fast_tanh, the second is the C++
	// function name that contains the implementation.
	{ "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr },

	// Terminate the array with an object containing nulls.
	{ nullptr, nullptr, 0, nullptr }
};

static PyModuleDef superfastcode_module = {
	PyModuleDef_HEAD_INIT,
	"module1",                        // Module name to use with Python import statements
	"Provides some functions, but faster",  // Module description
	0,
	superfastcode_methods                   // Structure that defines the methods of the module
};

PyMODINIT_FUNC PyInit_module1() {
	return PyModule_Create(&superfastcode_module);
}

同样将解决方案平台设置为Release和x64
在这里插入图片描述
然后右键项目名->生成,即可在(项目目录)\Project1\x64\Release路径下找到pyd文件。
在pyd文件生成过程中,可能会产生pythonXX_d.lib文件找不到的错误,是因为没有安装python的debug版本的问题,只需要运行python的安装程序,选择Modify->Next->勾选Download debug binaries,安装即可解决。
在这里插入图片描述
最后在产生的pyd文件目录下,新建python脚本测试,

import module1 as m
import math

print(m.fast_tanh(0.5))
print(math.tanh(0.5))

结果如下,

0.4621171572600098
0.46211715726000974

3.2 通过新建python扩展

在新建项目菜单可以直接选择Python扩展模块,
在这里插入图片描述
可能有的读者新建项目的时候没有这个选项,是因为安装VS的时候没有安装相应的组件,这时候只需要运行VS的安装程序->修改->勾选Python开发,特别是Python本机开发工具需要选中,最后修改后再次打开VS即可。
在这里插入图片描述
项目新建python扩展项目后,已经自动生成好了代码模板,和一些项目属性设置,就可以直接进行开发,生成pyd文件的过程也就和3.1的一致,如果生成过程产生报错,按照3.1的属性设置进行相应的修改即可,就不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值