Simon Shi的小站

人工智能,机器学习, 强化学习,大模型,自动驾驶

0%

C++ python Tutorial

[TOC]

环境配置VS Studio

c_cpp_properties.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"configurations": [
{
"name": "windows-gcc-x64",
"includePath": [
"${workspaceFolder}/**",
"C:/Users/Simon/.conda/envs/torch_gpu/include/",
"C:/Users/Simon/.conda/envs/torch_gpu/Lib/site-packages/numpy/core/include"
],
"compilerPath": "D:/Tools/Mingw/mingw64/bin/gcc.exe",
"cStandard": "${default}",
"cppStandard": "c++11",
"intelliSenseMode": "windows-gcc-x64",
"compilerArgs": []
}
],
"version": 4
}

tasks.json

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
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: g++编译前清理",
"command": "rm",
"args": [
"${workspaceRoot}/*.exe"
]
},
{
"label": "build c++Callpython",
"type": "shell",
"command": "g++",
"args": [
"-g", "c++_python.cpp",
"-I", "C:/Users/Simon/.conda/envs/torch_gpu/include/",
"-I", "C:/Users/Simon/.conda/envs/torch_gpu/Lib/site-packages/numpy/core/include",
"-L", "C:/Users/Simon/.conda/envs/torch_gpu/libs/*",
"-o", "c++_python.exe"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"dependsOn":[
"C/C++: g++编译前清理",
]
}
]
}

// g++ -g c++_python.cpp -L ./libs/* -o c++_python.exe
// -fdiagnostics-color=always

0. Test Run

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

#include "numpy/arrayobject.h"
#include "Python.h"

using namespace std;

// ref: https://wenku.baidu.com/view/01fab1346f175f0e7cd184254b35eefdc8d315cd.html

int demo0(){

Py_SetPythonHome(L"C:/Users/Simon/.conda/envs/torch_gpu");
Py_Initialize();
PyRun_SimpleString("print('hello')");
Py_Finalize();

}

1. C++传参

call python method, set parameter ,return value

常用的有两种方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
使用 PyTuple_New 创建元组, PyTuple_SetItem 设置元组值

PyObject* args = PyTuple_New(3);
PyObject* arg1 = Py_BuildValue("i", 100); // 整数参数
PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮点数参数
PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串参数
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
PyTuple_SetItem(args, 2, arg3);

# 直接使用Py_BuildValue构造元组

PyObject* args = Py_BuildValue("(ifs)", 100, 3.14, "hello");
PyObject* args = Py_BuildValue("()"); // 无参函数
原文链接:https://blog.csdn.net/tobacco5648/article/details/50890106

img

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
int demo1()
{
Py_SetPythonHome(L"C:/Users/Simon/.conda/envs/torch_gpu");
Py_Initialize();

PyObject *module = NULL;
PyObject *pFunc = NULL;
PyObject *pArg = NULL;
PyObject *value = NULL;
// 导入文件
module = PyImport_ImportModule("pthonnx_ru");

pFunc = PyObject_GetAttrString(module, "demo1"); // 找到函数地址
pArg = Py_BuildValue("(S)", "my is c++ test");
value = PyEval_CallObject(pFunc, pArg); // 调用函数
float val;
PyArg_Parse(value, "f", &val);
// PyArg_ParseTuple(value, "f", &val);
cout << "--val1--" << val << endl;

pFunc = PyObject_GetAttrString(module, "Add");
pArg = Py_BuildValue("i, i)", 21, 23);
value = PyEval_CallObject(pFunc, pArg);
PyArg_Parse(value, "f", &val);
cout << "--val2--" << val << endl;

PyRun_SimpleString("print('hello')");
Py_Finalize();

return 0;
}

2.传递List参数

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
int demo2()
{

cout << "Hello World" << endl;

Py_SetPythonHome(L"C:/Users/Simon/.conda/envs/torch_gpu");
Py_Initialize();

PyObject *module = NULL;
PyObject *pFunc = NULL;
PyObject *pArg = NULL;
// 导入文件
module = PyImport_ImportModule("pthonnx_ru");
// 找到函数地址
pFunc = PyObject_GetAttrString(module, "demo2");
// Set Parameter
PyObject *pyParams = PyList_New(0);
PyList_Append(pyParams, Py_BuildValue("i", 5)); // float
PyList_Append(pyParams, Py_BuildValue("i", 3));
PyObject *args = PyTuple_New(1);
PyTuple_SetItem(args, 0, pyParams);

// 调用函数
float val;
PyObject *value = PyEval_CallObject(pFunc, args);
PyArg_Parse(value, "f", &val);
// PyArg_ParseTuple(value, "f", &val);
cout << "--val--" << val << endl;

PyRun_SimpleString("print('hello')");
Py_Finalize();

return 0;
}

3 python类操作,类属性,类成员函数 Todo

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
int demo3()
{
cout << "Hello World" << endl;

Py_SetPythonHome(L"C:/Users/Simon/.conda/envs/torch_gpu");
Py_Initialize();

PyObject *module = NULL;
PyObject *pFunc = NULL;

module = PyImport_ImportModule("pthonnx_ru"); // 导入文件
pFunc = PyObject_GetAttrString(module, "demo2"); // 找到函数地址

// 创建参数
PyObject *pArgs = PyTuple_New(1);
// 设置函数参数的值
int InParm = 1;
PyTuple_SetItem(pArgs, 0, PyLong_FromLong(InParm));

// 调用函数
float val;
PyObject *value = PyEval_CallObject(pFunc, pArgs);
PyArg_Parse(value, "f", &val);
// PyArg_ParseTuple(value, "f", &val);
cout << "--val--" << val << endl;

Py_Finalize();
return 0;
}

4 传递c++数组转python的list

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
int demo4(){
Py_SetPythonHome(L"C:/Users/Simon/.conda/envs/torch_gpu");
Py_Initialize();
// #include "numpy/arrayobject.h"
// api doc : https://numpy.org/doc/1.17/reference/c-api.array.html#importing-the-api
import_array();

PyObject *module = NULL;
PyObject *pFunc = NULL;
PyObject *pArgs = NULL;

module = PyImport_ImportModule("pthonnx_ru");
pFunc = PyObject_GetAttrString(module, "demo4");

float buf[2][3];
buf[0][0] = 0;
buf[0][1] = 1.1230;
buf[0][2] = 2.340;
buf[1][0] = 4.540;
buf[1][1] = 6.900;
buf[1][2] = 8.090;

pArgs = PyTuple_New(1);
npy_intp dims[2] = {2, 3}; // 定义list的shape
int ND = 2; // list 维度
PyObject * pPyArray = PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, buf); // list dim,shape, type, buffer
PyTuple_SetItem(pArgs, 0, pPyArray); // 变量转换
PyEval_CallObject(pFunc, pArgs);

Py_Finalize();
return 0;
}

参考:

https://docs.python.org/2/extending/embedding.html

https://wenku.baidu.com/view/01fab1346f175f0e7cd184254b35eefdc8d315cd.html

https://numpy.org/doc/1.17/reference/c-api.array.html

https://numpy.org/doc/1.17/reference/c-api.array.html#importing-the-api