C++编写Python模块----相关设置

 

参考:

创建适用于 Python 的 C++ 扩展

https://docs.microsoft.com/zh-cn/visualstudio/python/working-with-c-cpp-python-in-visual-studio?view=vs-2017

Extending Python with C or C++

https://docs.python.org/2.7/extending/extending.html

 

项目属性配置:

1.选择release + x64编译模式,否则编译dll会报错,(python 是64位)

2.如下表所述设置项目属性,然后选择“确定”。

Tab属性“值”
常规常规 > 目标名称指定想要在 from...import 语句中从 Python 引用的模块的名称。 定义 Python 的模块时,在 C++ 中使用相同的名称。 如果想要将项目的名称用作模块名称,请保留默认值 $(ProjectName)。
 常规 > 目标扩展名.pyd
 项目默认值配置类型动态库(.dll)
C/C++常规附加包含目录根据相应的安装添加 Python“include” 文件夹,例如 c:\Python36\include
C/C++预处理器预处理器定义将 Py_LIMITED_API; 添加到字符串(包括分号)的开头。 此定义会限制可从 Python 调用的某些函数,并使代码在 Python 不同版本之间更易于移植。
C/C++代码生成运行时库多线程 DLL (/MD)(请参阅下面的“警告”)
链接器 > 常规附加库目录根据相应的安装添加包含 .lib 文件的 Python“libs”文件夹,例如 c:\Python36\libs。 (务必指向包含 .lib 文件的“libs”文件夹,而非包含 .py 文件的 Lib 文件夹。)

 提示

     如果在项目属性中未看到 C/C++ 选项卡,这是因为项目不包含标识为 C/C++ 源文件的任何文件。 如果创建的源文件不含 .c 或 .cpp 扩展名,则可能出现这种情况。 例如,如果之前在“新建项”对话框中不小心输入了 module.coo(而不是 module.cpp),则 Visual Studio 会创建文件,但不会将文件类型设置为“C/C+ 代码”,而正是它激活 C/C++ 属性选项卡。即使将文件重命名为带 .cpp,此类识别错误仍会存在。 为了正确设置文件类型,请在“解决方案资源管理器”中右键单击文件,选择“属性”,然后将“文件类型”设置为“C/C++ 代码”。

 警告

     即使对于调试配置,也始终将“C/C++” > “代码生成” > “运行时库”选项设置为“多线程 DLL (/MD)”,因为此设置是生成非调试 Python 二进制文件时使用的设置。 如果碰巧设置了“多线程调试 DLL (/MDd)”选项,则生成调试配置会产生错误“C1189: Py_LIMITED_API 与 Py_DEBUG、Py_TRACE_REFS 和 Py_REF_DEBUG 不兼容”。 此外,如果删除 Py_LIMITED_API 来避免出现生成错误,则在尝试导入模块时,Python 会崩溃。 (如下所述,崩溃将发生在 DLL 对 PyModule_Create 的调用中,并出现输出消息“严重 Python 错误: PyThreadState_Get: 无当前线程”。)

/MDd 选项用于生成 Python 调试二进制文件(例如 python_d.exe),但对扩展 DLL 选择此选项仍会导致 Py_LIMITED_API的生成错误。

 

测试代码:

#include <Python.h> 

//C++函数
int Add(int x, int y)
{
    return x + y;
}

int Del(int x, int y)
{
    return x - y;
}


//***********************************************************接口函数,以接受和返回 Python 类型
static PyObject* WrappAdd(PyObject* self, PyObject* args)
{
    int x, y;
    if (!PyArg_ParseTuple(args, "ii", &x, &y))
    {
        return NULL;
    }
    return Py_BuildValue("i", Add(x, y));
}

static PyObject* WrappDel(PyObject* self, PyObject* args)
{
    int x, y;
    if (!PyArg_ParseTuple(args, "ii", &x, &y))
    {
        return NULL;
    }
    return Py_BuildValue("i", Del(x, y));
}


//*************************************************************模块方法表,向 Python 呈现 C++ 中方法、函数的结构
static PyMethodDef py_module_methods[] = {
        { "Add", WrappAdd, METH_VARARGS, "Execute a shell command." },
        { "Del", WrappDel, METH_VARARGS, "Execute a shell command." },
        { NULL, NULL, 0, NULL } /* Sentinel */
};


//**************************************************************模块的初始化函数

//--- #define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
// PyMODINIT_FUNC 为宏定义,本身包含extern "C"
//extern "C"

PyMODINIT_FUNC initpy_module(void)
{    
    
    
    PyObject *m;
    m = Py_InitModule("py_module", py_module_methods);
    if (m == NULL)
        return;
    PyImport_AddModule("py_module");

}

/*

初始化函数的名称必须是init+模块名。这个函数必须是non-static的。
如动态库名字为py_module.pyd,则模块的初始化函数名必须是initpy_module,
且Py_InitModule()函数的第一个参数必须是“py_module”,否则Python导入模块会失败;

*/

 

 


 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值