1 C++工程配置python3.7
1.1 添加 include, libs, 链接器输入,dll
或者可以把python的dll放在c++工程目录下。
1.2 python脚本放在c++工程的根目录下。
2 Python脚本
PyForCS.py
# coding:utf-8
import sys
sys.path.append('./')
def multiply(a,b):
strs = """
I figure life is a gift and I don't intend on wasting it.
You never know what hand you're going to get dealt next.
You learn to take life as it comes at you…
我觉得生命是一份礼物,我不想浪费它,
你不会知道下一手牌会是什么,要学会接受生活。
"""
print(strs)
# c = 0
# for i in range(0, a):
# c = c + b
result1 = a + b
result2 = a*b
result3 = "hello China"
# return (a * b, a + b, "hello poem")
return (result1, result2, result3)
def get_int(a, b):
a *= 10
b *= 10
return a + b
def get_str(s1, s2, s3):
# return s1 + s2
print(s3)
return (s1 + s2, 10000, 20)
3 VS工程
3.1 元组和c++基础类型为传入参数cpp
#include "Python.h"
#include <string>
#include <iostream>
#pragma comment(lib, "python37.lib")
using namespace std;
int main5()
{
// 初始化Python
//在使用Python系统前,必须使用Py_Initialize对其
//进行初始化。它会载入Python的内建模块并添加系统路
//径到模块搜索路径中。这个函数没有返回值,检查系统
//是否初始化成功需要使用Py_IsInitialized。
Py_Initialize();
// 检查初始化是否成功
if (!Py_IsInitialized())
{
return -1;
}
// 添加当前路径
//把输入的字符串作为Python代码直接运行,返回0
//表示成功,-1表示有错。大多时候错误都是因为字符串
//中有语法错误。
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')"); //引入模块的地址
PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
// 载入名为pytest的脚本
pName = PyUnicode_FromString("PyForCS"); //脚本名子
pModule = PyImport_Import(pName);
if (!pModule)
{
printf("can't find pytest.py");
getchar();
return -1;
}
pDict = PyModule_GetDict(pModule); //返回模块命名空间
if (!pDict)
{
return -1;
}
// 找出函数名为add的函数,并执行add
pFunc = PyDict_GetItemString(pDict, "multiply");
if (!pFunc || !PyCallable_Check(pFunc))
{
printf("can't find function [add]");
getchar();
return -1;
}
// 参数进栈
pArgs = PyTuple_New(2); //一个参数数组
// PyObject* Py_BuildValue(char *format, ...)
// 把C++的变量转换成一个Python对象。当需要从
// C++传递变量到Python时,就会使用这个函数。此函数
// 有点类似C的printf,但格式不同。常用的格式有
// s 表示字符串,
// i 表示整型变量,
// f 表示浮点数,
// O 表示一个Python对象。
PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", 3));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", 4));
// 调用Python函数
int test_mul = 0;
int test_add = 0;
char* pstr = new char[100];
pValue = PyObject_CallObject(pFunc, pArgs);
//cout << "Result of call :" << PyLong_AsLong(pValue) << endl;
PyArg_ParseTuple(pValue, "i, i, s", &test_mul, &test_add, &pstr);
//PyArg_ParseTuple(pValue, " l, l, s", &test_mul, &test_add, &pstr);
printf("%d, %d, %s\n", test_mul, test_add, pstr);
Py_DECREF(pName);
Py_DECREF(pArgs);
Py_DECREF(pModule);
// 关闭Python
Py_Finalize();
system("pause");
return 0;
}
int main30()
{
Py_Initialize();
//pass a string containing Python statements to PyRun_SimpleString()
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
system("pause");
return 0;
}
3.2 Python返回元组
#include "Python.h"
#include <string>
#include <iostream>
#pragma comment(lib, "python37.lib")
using namespace std;
int main()
{
// 初始化Python
//在使用Python系统前,必须使用Py_Initialize对其
//进行初始化。它会载入Python的内建模块并添加系统路
//径到模块搜索路径中。这个函数没有返回值,检查系统
//是否初始化成功需要使用Py_IsInitialized。
Py_Initialize();
// 检查初始化是否成功
if (!Py_IsInitialized())
{
return -1;
}
// 添加当前路径
//把输入的字符串作为Python代码直接运行,返回0
//表示成功,-1表示有错。大多时候错误都是因为字符串
//中有语法错误。
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')"); //引入模块的地址
PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
// 载入名为pytest的脚本
pName = PyUnicode_FromString("PyForCS"); //脚本名子
pModule = PyImport_Import(pName);
if (!pModule)
{
printf("can't find pytest.py");
getchar();
return -1;
}
pDict = PyModule_GetDict(pModule); //返回模块命名空间
if (!pDict)
{
return -1;
}
// 找出函数名为add的函数,并执行add
pFunc = PyDict_GetItemString(pDict, "multiply");
if (!pFunc || !PyCallable_Check(pFunc))
{
printf("can't find function [add]");
getchar();
return -1;
}
// 参数进栈
pArgs = PyTuple_New(2); //一个参数数组
// PyObject* Py_BuildValue(char *format, ...)
// 把C++的变量转换成一个Python对象。当需要从
// C++传递变量到Python时,就会使用这个函数。此函数
// 有点类似C的printf,但格式不同。常用的格式有
// s 表示字符串,
// i 表示整型变量,
// f 表示浮点数,
// O 表示一个Python对象。
PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", 3));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", 4));
// 调用Python函数
int test_mul = 0;
int test_add = 0;
char* pstr = new char[100];
pValue = PyObject_CallObject(pFunc, pArgs);
//cout << "Result of call :" << PyLong_AsLong(pValue) << endl;
PyArg_ParseTuple(pValue, "iis", &test_mul, &test_add, &pstr);
//PyArg_ParseTuple(pValue, " l, l, s", &test_mul, &test_add, &pstr);
printf("%d, %d, %s\n", test_mul, test_add, pstr);
Py_DECREF(pName);
Py_DECREF(pArgs);
Py_DECREF(pModule);
// 关闭Python
Py_Finalize();
system("pause");
return 0;
}
3 Python 返回一个值
#include <iostream>
#include <Python.h>
#include <string>
using namespace std;
/*
This code loads a Python script using argv[1], and calls the function named in argv[2].
Its integer arguments are the other values of the argv array.
*/
int main()
{
string Filename = "PyForCS";
// initializing the interpreter
Py_Initialize();
if (!Py_IsInitialized())
{
return -1;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
pName = PyUnicode_FromString("PyForCS");
//使用string类的内部函数c_str(),使得string类型的对象变为char*类型;
//const char *c_str();
//c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同
//标准用法
/*应该这样用:
char c[20];
string s="1234";
strcpy(c,s.c_str()); */
/* Error checking of pName left out */
// the script is loaded using PyImport_Import()
pModule = PyImport_Import(pName);
//Py_DECREF(pName);
if (pModule)
{
// Once the script is loaded, the name we’re looking for is retrieved using PyObject_GetAttrString()
pFunc = PyObject_GetAttrString(pModule, "get_int");
/* pFunc is a new reference */
//向参数数组中加值
pArgs = PyTuple_New(2);
pValue = PyLong_FromLong(atoi("5"));
if (!pValue)
{
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, 0, pValue);
pValue = PyLong_FromLong(atoi("3"));
if (!pValue)
{
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, 1, pValue);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL)
{
printf("Result of call: %ld\n", PyLong_AsLong(pValue));
Py_DECREF(pValue);
}
}
else
{
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", "MyMultiply");
return 1;
}
if (Py_FinalizeEx() < 0)
{
return 120;
}
system("pause");
return 0;
}
4 python 文档
Format Strings for PyArg_ParseTuple()
https://docs.python.org/2.0/ext/buildValue.html
The Py_BuildValue() Function
https://docs.python.org/2.0/ext/buildValue.html