python中调用C++动态库函数

环境

  • 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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值