C++調用Python

最近在學習Python,主要是學習腳本語言,可以跨平臺,輕量級,擁有做一些測試的工具。當然也是因爲,看Boost書的時候,裏面說C++可以調用Python,所以就花了一段時間學習了下。現在開始學習C++調用Python.

安裝完Python後,安裝目錄下有頭文件include和libs,VS可以通過設置這兩個來引用Python.


項目設置很簡單,主要項目頭文件目錄設置爲include,庫目錄設置爲libs即可。

使用時只需要引用“Python.h”頭文件。

注意:1.debug下,python27.lib需要複製一份命名爲python27_d.lib

// CallPython.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include "Python.h"
#include <iostream>
using namespace std;

void TestCallFunc();
void TestCallFuncDict();
void TestClass();

int _tmain(int argc, _TCHAR* argv[])
{
	TestCallFunc();
	TestCallFuncDict();
	TestClass();
	getchar();
	return 0;
}

void TestCallFunc()
{
	Py_Initialize();	// 使用Python之前,要調用Py_Initialize初始化
	PyObject* pModule = NULL;
	PyObject* pFunc = NULL;
	PyObject* pAddFunc = NULL;
	pModule = PyImport_ImportModule("testPython");	// 加載模塊,加載py文件
	if (pModule)
	{
		// 加載函數,HelloWorld,無參數
		pFunc = PyObject_GetAttrString(pModule, "HelloWorld");	// 獲取模塊的函數
		if (pFunc)
		{
			PyEval_CallObject(pFunc, NULL);						// 調用函數,NULL表示參數爲空
			//Py_DECREF(pFunc);
		}
		else
		{
			cout << "pFunc = NULL" << endl;
		}
		// 加載函數,Add,兩個參數
		pAddFunc = PyObject_GetAttrString(pModule, "add");
		if (pAddFunc)
		{
			// 創建參數
			PyObject* pArgs = PyTuple_New(2);	// 函數調用的參數傳遞均是以元組的形式
			PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 5));	// 0 -- 序號,i表示創建int型變量
			PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 7));	// 1 -- 序號
			// 返回值
			PyObject* pReturn = NULL;
			//pReturn = PyEval_CallObject(pAddFunc, pArgs);
			// 傳入多個參數
			//pReturn = PyEval_CallFunction(pAddFunc, "ii", 5, 7);
			pReturn = PyObject_CallFunction(pAddFunc, "ii", 5, 7);
			
			
			// 將返回值轉爲int類型
			int result;
			PyArg_Parse(pReturn, "i", &result);
			cout << "5 + 7 = " << result << endl;

			//Py_DECREF(pAddFunc);

		}
		else
		{
			cout << "pAddFunc = NULL" << endl;
		}
	}
	else
	{
		cout << "pModule = NULL" << endl;
	}
	//Py_DECREF(pModule);
	Py_Finalize();		// 釋放
}

void TestCallFuncDict()
{
	Py_Initialize();
	PyObject* pModule = NULL;
	PyObject* pFunc = NULL;
	pModule = PyImport_ImportModule("testPython");
	if (pModule)
	{
		pFunc = PyObject_GetAttrString(pModule, "TestDict");
		if (pFunc)
		{
			// 設置參數字典
			PyObject* pArgs = PyTuple_New(1);
			PyObject* pDict = PyDict_New();
			PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "Longma"));
			PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25));
			PyTuple_SetItem(pArgs, 0, pDict);
			PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
			// 處理返回值
			int size = PyDict_Size(pReturn);
			cout << "返回字典的大小爲:" << size << endl;
			PyObject* pNewAge = PyDict_GetItemString(pReturn, "Age");
			int newAge = _PyInt_AsInt(pNewAge);
			//PyArg_Parse(pNewAge, "i", &newAge);
			cout << "True Age: " << newAge << endl;

			PyObject* pNewName = PyDict_GetItemString(pReturn, "Name");
			char* pName = PyString_AsString(pNewName);
			cout << "True Name: " << pName << endl;

			//Py_DECREF(pFunc);
		}
	}
	Py_Finalize();
}

void TestClass()
{
	Py_Initialize();
	PyObject* pModule = NULL;

	pModule = PyImport_ImportModule("testPython");
	if (pModule)
	{
		// 獲取Person類
		PyObject* pClassPerson = PyObject_GetAttrString(pModule, "Person");
		// 創建Person類實例
		PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);
		// 調用方法greet方法
		PyObject_CallMethod(pInstancePerson, "greet", "s", "Hello Kitty");
		// 傳入多個參數
		//PyObject_CallMethod(pInstancePerson, "greet", "si", "Hello Kitty", 10);
	}
	Py_Finalize();

}


Python代碼

testPython.py

def HelloWorld():  
    print "Hello World"  
def add(a, b):  
    return a+b  
def TestDict(dict):  
    print dict  
    dict["Age"] = 17
    dict["Name"] = "Royma"
    return dict  
class Person:  
    def greet(self, greetStr):  
        print greetStr


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章