环境
- win10 (64位)
- vs2017
- python3.6(64位)
vs2017需要安装组件如下图:
如果你想要在windows上使用mingw来编译生成DLL的话,会遇到不少的坑。建议使用vs,避免走弯路。
开发DLL库
打开vs,依次点击【文件】》【新建】》【项目】。然后选中面板中的【visual C++】》【Windows桌面】》【动态链接库】,填写上项目名称后,点击确定。如下图所示:
点击确定后,如下图所示,需要注意的是,因为我的系统是64位的,所以把x86改为x64。否则64位的python加载不了32位的DLL库,会提示不可用的win32程序。
开大Dll2.cpp,添加代码如下:
// Dll2.cpp: 定义 DLL 应用程序的导出函数。
#define EXPORT __declspec(dllexport)
#include<iostream>
using namespace std;
class TestDLL{
public:
void hello();
};
void TestDLL::hello() {
cout << "hello world" << endl;
}
extern "C" {
TestDLL td;
EXPORT void hello() {
td.hello();
}
EXPORT void hello1() {
cout << "hello world 111111" << endl;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
需要注意的是代码第一行中定义的EXPORT,如果实在linux环境下是用g++编译的话,就不需要这行代码,也就不需要下面extern中的EXPORT。
右键项目,点击【生成】,在输出中我们可以看到dll的输出目录。如下:
1>------ 已启动生成: 项目: Dll2, 配置: Debug x64 ------
1>Dll2.vcxproj -> F:\workspace\cplus\Dll2\x64\Debug\Dll2.dll
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
- 1
- 2
- 3
- 4
到这里我们的DLL库就生成成功。
python加载DLL库
代码如下:
import ctypes
lib = ctypes.cdll.LoadLibrary("F:/workspace/cplus/Dll2/x64/Debug/Dll2.dll")
lib.hello()
lib.hello1()
- 1
- 2
- 3
- 4
运行输出如下:
hello world
hello world 111111
[Finished in 0.3s]
- 1
- 2
- 3
说明调用成功
扩展python
打开vs2017,依次点击【文件】》【新建】》【项目】。然后选中面板中的【visual C++】》【Python】》【Python扩展模块】,填写上项目名称后,点击确定。如下图所示:
这里依旧要注意,要选择x64。源码路径中已经为我们生成了模版文件,helloext.c。打开内容如下:
#include <Python.h>
/*
* Implements an example function.
*/
PyDoc_STRVAR(helloext_example_doc, "example(obj, number)\
\
Example function");
PyObject *helloext_example(PyObject *self, PyObject *args, PyObject *kwargs) {
/* Shared references that do not need Py_DECREF before returning. */
PyObject *obj = NULL;
int number = 0;
/* Parse positional and keyword arguments */
static char* keywords[] = { "obj", "number", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi", keywords, &obj, &number)) {
return NULL;
}
/* Function implementation starts here */
if (number < 0) {
PyErr_SetObject(PyExc_ValueError, obj);
return NULL; /* return NULL indicates error */
}
Py_RETURN_NONE;
}
/*
* List of functions to add to helloext in exec_helloext().
*/
static PyMethodDef helloext_functions[] = {
{ "example", (PyCFunction)helloext_example, METH_VARARGS | METH_KEYWORDS, helloext_example_doc },
{ NULL, NULL, 0, NULL } /* marks end of array */
};
/*
* Initialize helloext. May be called multiple times, so avoid
* using static state.
*/
int exec_helloext(PyObject *module) {
PyModule_AddFunctions(module, helloext_functions);
PyModule_AddStringConstant(module, "__author__", "Administrator");
PyModule_AddStringConstant(module, "__version__", "1.0.0");
PyModule_AddIntConstant(module, "year", 2018);
return 0; /* success */
}
/*
* Documentation for helloext.
*/
PyDoc_STRVAR(helloext_doc, "The helloext module");
static PyModuleDef_Slot helloext_slots[] = {
{ Py_mod_exec, exec_helloext },
{ 0, NULL }
};
static PyModuleDef helloext_def = {
PyModuleDef_HEAD_INIT,
"helloext",
helloext_doc,
0, /* m_size */
NULL, /* m_methods */
helloext_slots,
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC PyInit_helloext() {
return PyModuleDef_Init(&helloext_def);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
模版中的注释很清晰,我们按照注释添加一个简单的example函数,添加代码如下图所示:
完整代码如下:
#include <Python.h>
#include <stdio.h>
/*
* Implements an example function.
*/
PyDoc_STRVAR(helloext_example_doc, "example(obj, number)\
\
Example function");
void example(obj,number) {
printf("hello world");
}
PyObject *helloext_example(PyObject *self, PyObject *args, PyObject *kwargs) {
/* Shared references that do not need Py_DECREF before returning. */
PyObject *obj = NULL;
int number = 0;
/* Parse positional and keyword arguments */
static char* keywords[] = { "obj", "number", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi", keywords, &obj, &number)) {
return NULL;
}
/* Function implementation starts here */
example();
if (number < 0) {
PyErr_SetObject(PyExc_ValueError, obj);
return NULL; /* return NULL indicates error */
}
Py_RETURN_NONE;
}
/*
* List of functions to add to helloext in exec_helloext().
*/
static PyMethodDef helloext_functions[] = {
{ "example", (PyCFunction)helloext_example, METH_VARARGS | METH_KEYWORDS, helloext_example_doc },
{ NULL, NULL, 0, NULL } /* marks end of array */
};
/*
* Initialize helloext. May be called multiple times, so avoid
* using static state.
*/
int exec_helloext(PyObject *module) {
PyModule_AddFunctions(module, helloext_functions);
PyModule_AddStringConstant(module, "__author__", "Administrator");
PyModule_AddStringConstant(module, "__version__", "1.0.0");
PyModule_AddIntConstant(module, "year", 2018);
return 0; /* success */
}
/*
* Documentation for helloext.
*/
PyDoc_STRVAR(helloext_doc, "The helloext module");
static PyModuleDef_Slot helloext_slots[] = {
{ Py_mod_exec, exec_helloext },
{ 0, NULL }
};
static PyModuleDef helloext_def = {
PyModuleDef_HEAD_INIT,
"helloext",
helloext_doc,
0, /* m_size */
NULL, /* m_methods */
helloext_slots,
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC PyInit_helloext() {
return PyModuleDef_Init(&helloext_def);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
右键项目,点击【生成】,输出如下所示:
1>------ 已启动生成: 项目: helloext, 配置: Debug x64 ------
1>F:\workspace\cplus\helloext\helloext\helloext.vcxproj(200,5): warning : Python debug symbols are not installed. Installing the symbols through the Python installer is strongly recommended.
1>helloext.c
1>helloext.vcxproj -> F:\workspace\cplus\helloext\x64\Debug\helloext.pyd
1>已完成生成项目“helloext.vcxproj”的操作。
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
- 1
- 2
- 3
- 4
- 5
- 6
- 7
OK,到这里我们生成了helloext.pyd文件。然后把生成的helloext.pyd文件复制到python安装目录下的DLLs目录下。然后就可以在python中import了。python代码如下:
import helloext
helloext.example("",2)
- 1
- 2
输出结果如下:
hello world[Finished in 0.1s]
- 1
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
</div>