zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python和c交互

Python 交互
2023-06-13 09:14:11 时间

python调用c++

  • 使用pybind11或者boost.python
char const* greet()
{
   return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("greet", greet);
}

定义python的函数

  • 使用ctypes调用c模块文件

CDLL(“dll_name.dll”,winmode=0)加载dll,还有WINDLL、PYDLL

python3.8以后版本加winmode、以前的版本不加 导出函数使用extern ”C“ structure结构体封装

class T(structure):
	_fields_=[('a',1),('b',2)]   //添加成员a和b

pointer取地址ctypes类型、id取地址python类型 回调函数调用

def message():
	return "123"
CFUNCTYPE(c_wchar_p)(message)    //返回数据有内存泄漏

类型转换

cast(Point(c_int),c_void_p)    //int*转void*

函数指定参数和返回值

pfunc.create.restype = c_void_p   //指定参数为c_void_p
//c++数据,传入python不声明类型,存在潜在问题
p = pfunc.create()   
pfunc.test(p)    //返回的p不能直接调用

c调用python

使用python的头文件Python.h

  • 执行python字符串的调用方式,返回值在控制台中需要捕获
string line;
std::error_code ec;
boost::process::ipstream is;
boost::process::system("where python", process::std_out>is, 
    ec,process::windows::create_no_window);
std::getline(is, line);
Py_SetPythonHome(boost::locale::conv::to_utf<wchar_t>(
    boost::filesystem::path(line).parent_path().string(), "gbk").c_str());
Py_Initialize();
if(!Py_IsInitialized()){
    cout<<"init python error";
    return -1;
}
PyRun_SimpleString(("import sys\nsys.path.append(r'"+boost::filesystem::path(argv[1]).parent_path().string()+"')").c_str());
  • 执行字符串,表达式并返回值
//#define Py_single_input 256   
//#define Py_file_input 257
//#define Py_eval_input 258         //
//#define Py_func_type_input 345
PyRun_String(ss.str().c_str(), Py_single_input ,py_dict,py_dict);
  • 执行单个函数,Py_BuildValue转换c的类型为python类型
PyRun_SimpleString(("import sys\nsys.path.append(r'"+filesystem::path(argv[1]).parent_path().string()+"')").c_str());
PyObject* pyModule = PyImport_ImportModuleNoBlock(filesystem::path(argv[1]).stem().string().c_str());
if (pyModule != NULL) {
    PyObject* pyFunc = PyObject_GetAttrString(pyModule, filesystem::path(argv[1]).stem().string().c_str());
    if (pyFunc != NULL) {
        if (PyCallable_Check(pyFunc) != 0){
            PyObject* result = NULL;
            //PyObject* arg = Py_BuildValue("s",argv[2]);
            result = PyObject_CallFunction(pyFunc,argv[2]);
            //result = PyObject_CallObject(pyFunc, NULL);
            //Py_DECREF(arg);
            //if (result != NULL) Py_DECREF(result);
            cout << (char*)PyUnicode_DATA(PyObject_Str(result));
        }
        //Py_DECREF(pyModule);
    }
}

异常问题

  • Py_DECREF链接失败

Py_DECREF函数调试和发布的lib不同,需要对应正确的版本才行,用release替换debug是不行的,建议导入python.org官网下载编译(源码项目有bat和configure文件可以编译)