用VS 编写 Python C扩展

参考文章

官方文档   https://docs.python.org/3/extending/extending.html#calling-python-functions-from-c

微软文档      https://docs.microsoft.com/en-us/visualstudio/python/cpp-and-python

微软文档的例子比较简单一些,我就就拷贝它的例子。如果python也用vs集成开发环境,你还可以debug 你的c扩展,里面也有介绍。


在vs里新建一个空项目,然后设置 target extension 和 configuration type, target extension 可以为dll或者pyd,但如果设置为dll的话,到时候记得把编译后的dll后缀

手动改成pyd,因为python import的时候,默认去找py pyd等后缀的,不找dll为后缀的,如果只是dll的会出现 ModuleNotFoundError: No module named xx

   因为需要使用到python.h, 你需要把python安装目录下的 包含python.h 的include包含进来,还需要设置python  lib目录以及 lib

我用的是anaconda3。



用VS 编写 Python C扩展_第1张图片



用VS 编写 Python C扩展_第2张图片


    

#include "python.h"


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

	static PyMethodDef hello_methods[] = {
		// The first property is the name exposed to python, the second is the C++ function name        
		{ "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr },

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


	static PyModuleDef hello_module = {
		PyModuleDef_HEAD_INIT,
		"hello",                        // Module name
		"Provides some functions, but faster",  // Module description
		0,
		hello_methods                   // Structure that defines the methods
	};

	PyMODINIT_FUNC PyInit_hello() {
		return PyModule_Create(&hello_module);
	}

	extern "C" __declspec(dllexport) int  testExport(){
		printf(__FUNCTION__);

		return 0;
	}

        编译出来后 如果用 import  的方式使用这个 hello.pyd

>>> import hello
>>> hello.__dict__
{'__name__': 'hello', '__doc__': 'Provides some functions, but faster', '__packa
ge__': '', '__loader__': <_frozen_importlib_external.ExtensionFileLoader object
at 0x00000000027CC320>, '__spec__': ModuleSpec(name='hello', loader=<_frozen_imp
ortlib_external.ExtensionFileLoader object at 0x00000000027CC320>, origin='D:\\c
ode\\test\\x64\\Release\\hello.pyd'), 'fast_tanh':
, '__file__': 'D:\\code\\test\\x64\\Release\\hello.pyd'}
>>> dir(hello)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fast_tanh']


>>> hello.fast_tanh(20)
2.0

  可以看到我们想导出的 fast_tanh是在里面的,可以像使用python模块一样正常使用。

这个例子中我增加了一个 testExport()函数,这个testExport只能通过ctypes导入dll的方式使用,

详见 ctypes的官方文档,ctypes提供了python直接调用dll中导出函数的功能。LoadLibrary 无所谓dll还是pyd,只要文件名正确即可。



import ctypes
hello = ctypes.cdll.LoadLibrary("hello.dll")

>>> hello.testExport()
testExport0


   这是python和 C函数的交互。





你可能感兴趣的:(用VS 编写 Python C扩展)