我正在转换到删除代码中的boost-python依赖项,并且我已经进入了最后一步"这个过渡(我删除了所有其他的boost依赖项,当我注释掉下面的boost代码时,我得到ImportError: dynamic module does not define init function (initMy_module
)。
以下是代码
#include <boost/python.hpp>
namespace bpn = boost::python::numeric;
using namespace boost::python;
BOOST_PYTHON_MODULE(My_module)
{
using namespace bpn;
import_array();
array::set_module_and_type("numpy", "ndarray");
register_exception_translator<int>(&translator);
def("run_My_module", run_My_module, "run my moduule");
def("run_My_module_another_way", run_My_module_another_way, "run my module another way");
}
根据我对python / C API的理解,我认为以下代码应该表面上链接我的C和Python代码。
static PyMethodDef myModule_methods[] = {
{"run_My_module", run_My_module, METH_VARARGS},
{"run_My_module_another_way", run_My_module_another_way, METH_VARARGS},
{NULL, NULL}
};
void initmyModule(void)
{
// Init module.
(void) Py_InitModule("myModule", myModule_methods);
}
但是,这会产生以下错误:
myModule_python_binding.cpp:126:5: error: invalid conversion from 'int (*)(char*, char*, char*, PyObject*) {aka int (*)(char*, char*, char*, _object*)}' to 'PyCFunction {aka _object* (*)(_object*, _object*)}' [-fpermissive]
};
^
myModule_python_binding.cpp:126:5: error: invalid conversion from 'int (*)(char*, ompi_communicator_t*&, char*, char*, PyObject*) {aka int (*)(char*, ompi_communicator_t*&, char*, char*, _object*)}' to 'PyCFunction {aka _object* (*)(_object*, _object*)}' [-fpermissive]
这两种功能都是这种形式。它们都返回整数,表明它们的成功程度。
int run_myModule(char *infile, char *outfile, char *errfile, pyObject *exc)
{...};
int run_myModule_another_way(char *infile, int &_exvar, char *outfile, char *errfile, pyObject *exc)
{...};
为什么我的&#34;表面&#34;连接失败?
答案 0 :(得分:1)
您收到编译时错误,因为您在myModule_methods[]
中使用的函数指针的类型/签名错误。要直接从Python调用的函数需要具有以下签名:
PyObject *foo(PyObject *self, PyObject *args)
因此,如果您想从Python调用run_my_Module
和run_my_Module_another_way
函数,则需要在函数和Python之间创建必要的“粘合剂”,方法是将它们包装在具有上述签名的函数中。例如:
static PyObject *run_My_module_wrapper(PyObject *self, PyObject *args)
{
// Parse arguments from Python out of the args parameter using
// PyArg_ParseTuple. i.e. somthing like:
const char *infile, *outfile, *errfile;
PyObject *exc;
if (!PyArg_ParseTuple(args, "sssO", &infile, &outfile, &errfile, &exc)) {
return NULL; // Invalid arguments
}
//
// Now you can call your function with the arguments from the Python call.
//
int r = run_My_module(infile, outfile, errfile, exc);
if (r == SUCCESSFUL_VALUE) {
Py_RETURN_NONE;
}
else {
return NULL;
}
}
// Similar setup for run_My_module_another_way.
static PyMethodDef myModule_methods[] = {
{"run_My_module", run_My_module_wrapper, METH_VARARGS},
{"run_My_module_another_way", run_My_module_another_way_wrapper, METH_VARARGS},
{NULL, NULL}
};
void initmyModule(void)
{
// Init module.
(void) Py_InitModule("myModule", myModule_methods);
}
有关解析从Python传入的参数的更多信息,请参阅Parsing Arguments。加上Extending and Embedding the Python Interpreter获取您需要的所有常规信息。