参考文档:
接口指引:https://py3c.readthedocs.io/en/latest/guide-modernization.html
扩展和嵌入 Python 解释器:https://docs.python.org/zh-cn/3/extending/index.html
Python/C API 参考手册:https://docs.python.org/zh-cn/3/c-api/index.html
C++传递Python类型问题【注释为Python2】:
python2中某些类型与python3不兼容,可直接使用替换接口
//PyInt_FromLong(var);
PyLong_FromLong(var); //直接替换
//PyString_FromString(str);
PyBytes_FromFormat("%s", tokens[i].buffer); //该形式的替换能够保留编码,返回给Python3是encode后的结果
//PyUnicode_FromFormat("%s", tokens[i].buffer); // 该形式返回给python3即为Unicode编码,原python2代码多有问题,一般应该不会采用
Python传递参数给C++函数:PyArg_ParseTuple
注意Python2与Python3关于中文字符类型的差异【string和bytes的概念】
参照文档选择合适的格式类型:https://docs.python.org/3.7/c-api/arg.html
文档中相关符号的含义为:
"s" | (str) | [const char *] |
---|---|---|
fortmat元素表示 | Python中的数据类型 | C++中的数据类型 |
尤其需要关注中文字符编码的字符串传输,python2中s是经过encode后编码的输入,python3中s是Unicode编码的输入,如要和python2保持一致,可以改用"s#";
若Python代码中传入Unicode,在C++中使用encode后的结果,可以使用"et",使用方法如下:
const char* codetype = "gb18030";
char* text;
PyArg_ParseTuple(args, "et", codetype, &text)
创建模块的声明【注释为python2】:
/*
PyMODINIT_FUNC initlibwordseg_py(void) {
PyObject* m = Py_InitModule("libwordseg_py", WordSegMethods);
if (m == NULL) {
return;
}
WordSegError = PyErr_NewException("wordseg.error", NULL, NULL);
Py_INCREF(WordSegError);
PyModule_AddObject(m, "error", WordSegError);
PyObject* dict = PyModule_GetDict(m);
PyDict_SetItemString(dict, "SCW_BASIC", PyLong_FromLong(SCW_OUT_BASIC));
PyDict_SetItemString(dict, "SCW_WPCOMP", PyLong_FromLong(SCW_OUT_WPCOMP));
PyDict_SetItemString(dict, "SCW_SUBPH", PyLong_FromLong(SCW_OUT_SUBPH));
PyDict_SetItemString(dict, "SCW_HUMANNAME", PyLong_FromLong(SCW_OUT_HUMANNAME));
PyDict_SetItemString(dict, "SCW_BOOKNAME", PyLong_FromLong(SCW_OUT_BOOKNAME));
PyDict_SetItemString(dict, "SCW_NEWWORD", PyLong_FromLong(SCW_OUT_NEWWORD));
PyDict_SetItemString(dict, "SCW_DISAMB", PyLong_FromLong(SCW_OUT_DISAMB));
PyDict_SetItemString(dict, "SCW_PROP", PyLong_FromLong(SCW_OUT_PROP));
};
*/
// 绑定Module和Methods
static struct PyModuleDef WordSeg_module =
{
PyModuleDef_HEAD_INIT,
"WordSeg_module",
"",
-1,
WordSegMethods
};
//初始化Module
PyMODINIT_FUNC PyInit_libwordseg_py(void) { //函数名 libwordseg_py要与最后生成的so名字保持一致
// 创建模块
PyObject* m = PyModule_Create(&WordSeg_module);
// 输出ERROR信息
WordSegError = PyErr_NewException("wordseg.error", NULL, NULL);
Py_INCREF(WordSegError);
PyModule_AddObject(m, "error", WordSegError);
// 绑定输出词典
PyObject* dict = PyModule_GetDict(m);
PyDict_SetItemString(dict, "SCW_BASIC", PyLong_FromLong(SCW_OUT_BASIC));
PyDict_SetItemString(dict, "SCW_WPCOMP", PyLong_FromLong(SCW_OUT_WPCOMP));
PyDict_SetItemString(dict, "SCW_SUBPH", PyLong_FromLong(SCW_OUT_SUBPH));
PyDict_SetItemString(dict, "SCW_HUMANNAME", PyLong_FromLong(SCW_OUT_HUMANNAME));
PyDict_SetItemString(dict, "SCW_BOOKNAME", PyLong_FromLong(SCW_OUT_BOOKNAME));
PyDict_SetItemString(dict, "SCW_NEWWORD", PyLong_FromLong(SCW_OUT_NEWWORD));
PyDict_SetItemString(dict, "SCW_DISAMB", PyLong_FromLong(SCW_OUT_DISAMB));
PyDict_SetItemString(dict, "SCW_PROP", PyLong_FromLong(SCW_OUT_PROP));
return m;
}