c/c++ 调用python函数

众所周知,使用c/c++处理execl文件是很麻烦的事情,而python利用pandas库处理excel非常方便,所以这里使用c/c++调用python函数处理excel

环境:(这里使用的是mac系统)

python3.7

c++11

直接上代码:

python文件代码

import pandas as pd

def AdditionFc(a, b):
    print("Now is in python model")
    print(f"{a} + {b} = {a + b}")
    return a + b

def openXlsx(path):
    df = pd.read_excel(path)
    c = df.columns.values.tolist()
    r = df.index.values.tolist()
    data = []
    for i in r:
        row = []
        for j in range(len(c)):
            row.append(df.iloc[i, j])
        data.append(row)
    return data[0]

def openXlsxStr(path):
    df = pd.read_excel(path)
    c = df.columns.values.tolist()
    r = df.index.values.tolist()
    data = []
    for i in r:
        row = []
        for j in range(len(c)):
            row.append(df.iloc[i, j])
        data.append(row)
    return c[0]

def openXlsxList(path):
    df = pd.read_excel(path)
    c = df.columns.values.tolist()
    r = df.index.values.tolist()
    data = []
    for i in r:
        row = []
        for j in range(len(c)):
            row.append(df.iloc[i, j])
        data.append(row)
    return data
#include <stdio.h>
#include </Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m/Python.h>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

/*
    命令												实际输入

Py_BuildValue("")										None
Py_BuildValue(“i”, 123)									123
Py_BuildValue(“iii”, 123, 456, 789)						(123, 456, 789)
Py_BuildValue(“s”, “hello”)								‘hello’
Py_BuildValue(“ss”, “hello”, “world”)					(‘hello’, ‘world’)
Py_BuildValue(“s#”, “hello”, 4)							‘hell’
Py_BuildValue("()")										()
Py_BuildValue("(i)", 123)								(123,)
Py_BuildValue("(ii)", 123, 456)							(123, 456)
Py_BuildValue("(i,i)", 123, 456)						(123, 456)
Py_BuildValue("[i,i]", 123, 456)						[123, 456]
Py_BuildValue("{s:i,s:i}", “abc”, 123, “def”, 456)		{‘abc’: 123, ‘def’: 456}
Py_BuildValue("((ii)(ii)) (ii)", 1, 2, 3, 4, 5, 6)		(((1, 2), (3, 4)), (5, 6))

*/

void printVectorInt(const vector<int>& v)
{
    for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

// 无参函数调用 python 函数无返回值
int python_test_null()
{
	// 1、初始化python接口  
	Py_Initialize();
	if(!Py_IsInitialized()){
		cout << "python init fail" << endl;
		return 0;
	}
    // 2、初始化python系统文件路径,保证可以访问到 .py文件
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./script')");
 
    // 3、调用python文件名,不用写后缀
	PyObject* pModule = PyImport_ImportModule("sayhello");
	if( pModule == NULL ){
		cout <<"module not found" << endl;
		return 1;
	}
    // 4、调用函数
	PyObject* pFunc = PyObject_GetAttrString(pModule, "say");
	if( !pFunc || !PyCallable_Check(pFunc)){
		cout <<"not found function add_num" << endl;
		return 0;
	}
    // 
    PyObject_CallObject(pFunc, NULL);
    // 5、结束python接口初始化
	Py_Finalize();
    return 0;
}


// 有参函数调用 python 函数返回一个整数
int python_test()
{
	Py_Initialize(); //1、初始化python接口
    
    //初始化使用的变量
    PyObject* pModule = NULL;
    PyObject* pFunc = NULL;
    PyObject* pName = NULL;
    
	/* 添加模块路径 */
    //2、初始化python系统文件路径,保证可以访问到 .py文件
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./script')");
    
    //3、调用python文件名。当前的测试python文件名是 myadd.py  导入模块
    // 在使用这个函数的时候,只需要写文件的名称就可以了。不用写后缀。
    pModule = PyImport_ImportModule("myadd");
    
    //4、调用函数  导入函数
    pFunc = PyObject_GetAttrString(pModule, "AdditionFc");
    
    //5、给python传参数
    // 函数调用的参数传递均是以元组的形式打包的,2表示参数个数
    // 如果AdditionFc中只有一个参数时,写1就可以了
    PyObject* pArgs = PyTuple_New(2);
 
    // 0:第一个参数,传入 int 类型的值 2
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 2)); 
    // 1:第二个参数,传入 int 类型的值 4
    PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4)); 
    
    // 6、使用C++的python接口调用该函数
    PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
    
    // 7、接收python计算好的返回值
    int nResult;
    // i表示转换成int型变量。
    // 在这里,最需要注意的是:PyArg_Parse的最后一个参数,必须加上“&”符号
    PyArg_Parse(pReturn, "i", &nResult);
    cout << "return result is " << nResult << endl;
    
    //8、结束python接口初始化
    Py_Finalize();
	return 0;
}


// 有参函数调用,python函数返回一个一维列表
void python_return_list()
{
    /* 1、初始化python接口 */
    Py_Initialize();
    /* 2、初始化python系统文件和pandas库文件 */
    PyRun_SimpleString("import sys");
    // PyRun_SimpleString("import pandas as pd");
    PyRun_SimpleString("sys.path.append('./script')");
    /* 3、调用python文件名。当前的测试python文件名是 myadd.py  导入模块 不用添加.py后缀 */
    PyObject* pModule = PyImport_ImportModule("myadd");
    /* 4、调用函数  导入函数 */
    PyObject* pFunc = PyObject_GetAttrString(pModule, "openXlsx");
    
    /* 5、给python传参数 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 */
    PyObject* pArgs = PyTuple_New(1);
    // 传入 char* 类型的值 path
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "/Users/python_workstation/Desktop/test.xlsx"));
    
    /*  6、使用C++的python接口调用该函数 */
    PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
    /* 7、接收python的返回值 一维列表*/
    vector<int> dataInt;
    int listSize = PyList_Size(pReturn); // 获取返回的列表长度
    int temp;
    for (int i = 0; i < listSize; i++)
    {
        PyArg_Parse(PyList_GetItem(pReturn, i), "i", &temp);
        dataInt.push_back(temp);
    }
    Py_Finalize();

    printVectorInt(dataInt);
}

// 有参函数调用,python函数返回一个字符串
void python_return_str()
{
    /* 1、初始化python接口 */
    Py_Initialize();
    /* 2、初始化python系统文件和pandas库文件 */
    PyRun_SimpleString("import sys");
    // PyRun_SimpleString("import pandas as pd");
    PyRun_SimpleString("sys.path.append('./script')");
    /* 3、调用python文件名。当前的测试python文件名是 myadd.py  导入模块 不用添加.py后缀 */
    PyObject* pModule = PyImport_ImportModule("myadd");
    /* 4、调用函数  导入函数 */
    PyObject* pFunc = PyObject_GetAttrString(pModule, "openXlsxStr");
    
    /* 5、给python传参数 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 */
    PyObject* pArgs = PyTuple_New(1);
    // 传入 char* 类型的值 path
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "/Users/python_workstation/Desktop/test.xlsx"));
    
    /*  6、使用C++的python接口调用该函数 */
    PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
    /* 7、接收python的返回值 一个字符串*/
    char* pstr = NULL;
    PyArg_Parse(pReturn, "s", &pstr);
    cout << pstr << endl;
    Py_Finalize();
}

// 有参函数调用,python函数返回一个二维列表
void python_return_list_two()
{
    /* 1、初始化python接口 */
    Py_Initialize();
    /* 2、初始化python系统文件和pandas库文件 */
    PyRun_SimpleString("import sys");
    // PyRun_SimpleString("import pandas as pd");
    PyRun_SimpleString("sys.path.append('./script')");
    /* 3、调用python文件名。当前的测试python文件名是 myadd.py  导入模块 不用添加.py后缀 */
    PyObject* pModule = PyImport_ImportModule("myadd");
    /* 4、调用函数  导入函数 */
    PyObject* pFunc = PyObject_GetAttrString(pModule, "openXlsxList");
    
    /* 5、给python传参数 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 */
    PyObject* pArgs = PyTuple_New(1);
    // 传入 char* 类型的值 path
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "/Users/python_workstation/Desktop/test.xlsx"));
    
    /*  6、使用C++的python接口调用该函数 */
    PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
    /* 7、接收python的返回值 一个二维数字列表*/
    int temp;
    
    // 获得序列长度
    Py_ssize_t rsize = PyObject_Size(pReturn);

    cout << "rsize: " << rsize << endl;
    PyObject* iter = PyObject_GetIter(pReturn);
    while (true)
    {
        //获取列表的第一行
        PyObject* next = PyIter_Next(iter);
        if (!next)
        {
            break;
        }
        if (!PyList_Check(next))
        {
            cout << "error, we were expecting a list value" << endl;
        }
        Py_ssize_t foosize = PyObject_Size(next);

        PyObject* iter2 = PyObject_GetIter(next);
        while (true)
        {
            PyObject* next2 = PyIter_Next(iter2);
            if (!next2)
            {
                break;
            }
            if (!PyList_Check(next))
            {
                cout << "error, we were expecting a list value" << endl;
            }
            double foo = PyFloat_AsDouble(next2);
            cout << foo << " ";
        }
        cout << endl;
    }
    Py_Finalize();
}


int main(int argc, char *argv[])
{
	python_return_list_two();

	return 0;
}

 输出结果:

 

clang++ python_test.cpp -I/usr/local/python3.7m -o python_test -L/Library/Frameworks/Python.framework/Versions/3.7/lib -lpython3.7m

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值