1. 程式人生 > >C++程序調用python3

C++程序調用python3

docs tuple system rtm style exe 輸出 python 加載模塊

今天想做一個簡單的管理密碼的小程序,由於最近了解了下Python,就想用Python來寫。但是看了看Python的界面庫用法有感覺有點麻煩,所以還不如直接使用MFC寫寫界面,關於csv的文件處理部分使用Python來做,這樣可能會簡單些。

版本

vs使用2013版本

python使用3.6

notepad++配置python環境

https://www.cnblogs.com/huangsitao/p/10323198.html

VS中配置Python環境

1.在C++中調用Python需要包含“Python.h”頭文件,通過everything搜索找到"Python.h",默認路徑為C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\include

2.找到lib文件,我的是Python36.lib,默認路徑為C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\libs

3.將include目錄和libs目錄拷貝一份保存到sln同級目錄(因為在這個解決方案中我要寫C++調用Python的程序)

4.在vs中對應的工程上右鍵->屬性,C/C++->常規->附加包含目錄填寫include路徑,鏈接器->常規->附加庫目錄填寫lib路徑,鏈接器->輸入->附加依賴項填寫python36.lib

5.main.cpp中編寫下面代碼,編譯沒有問題說明配置成功

1 #include<Python.h>
2 int main()
3 {
4      return 0;  
5 }

開始寫代碼

初始化

Py_Initialize(); //載入Python的內建模塊並添加系統路徑到模塊搜索路徑中。無返回值

檢查是否初始化成功

Py_IsInitialized();

添加當前路徑到系統路徑中

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(‘./‘)");

PyRun_SimpleString為執行Python語句的函數。

加載python腳本文件

首先要寫好pytest.py文件放到exe同級目錄下。

pMoudle為NULL說明加載失敗,失敗的可能原因有:

1.找不到pytest.py文件,可能未將pytest.py文件拷貝到exe同級目錄或者為設置當前路徑為系統路徑

2.pytest.py腳本有語法錯誤(我的就是這種原因,2.0和3.0的python語法不同,直接將別人的pytest代碼拷貝過來未檢查導致失敗)

PyObject* pModule = PyImport_ImportModule("pytest");

獲取到函數

PyObject* func = PyObject_GetAttrString(pModule, "add");

檢查函數是否獲取成功

if (!PyCallable_Check(func))
{
    std::cout << "not find add function." << std::endl;
    return -1;
}

設置調用函數的參數

調用Python函數,參數和返回值都必須為元組

PyObject* args = PyTuple_New(2);
PyObject* arg1 = PyLong_FromLong(4);
PyObject* arg2 = PyLong_FromLong(3);
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);

調用函數

PyObject* pValue = PyObject_CallObject(func, args);

輸出返回值

if (pValue != NULL)
{
    printf("Result of call: %ld\n", PyLong_AsLong(pValue));
    Py_DECREF(pValue);
}

釋放資源

Py_Finalize();

完整代碼

 1 #include<iostream>
 2 #include<Python.h>
 3 
 4 int main()
 5 {
 6     Py_Initialize();
 7     // 檢查初始化是否成功  
 8     if (!Py_IsInitialized()) {
 9         return -1;
10     }
11     // 添加當前路徑,可以避免導入模塊輸入全路徑
12     PyRun_SimpleString("import sys");
13     PyRun_SimpleString("print (‘---import sys---‘)");
14     PyRun_SimpleString("sys.path.append(‘./‘)");
15     // 載入名為pytest的腳本  
16     PyObject* pModule = PyImport_ImportModule("pytest");
17     if (!pModule) // 加載模塊失敗
18     {
19         std::cout << "[ERROR] Python get module failed." << std::endl;
20         system("pause");
21         return 0;
22     }
23     std::cout << "[INFO] Python get module succeed." << std::endl;
24 
25     PyObject* func = PyObject_GetAttrString(pModule, "add");
26     if (!PyCallable_Check(func))
27     {
28         std::cout << "not find add function." << std::endl;
29         system("pause");
30         return -1;
31     }
32     PyObject* args = PyTuple_New(2);
33     PyObject* arg1 = PyLong_FromLong(4);
34     PyObject* arg2 = PyLong_FromLong(3);
35     PyTuple_SetItem(args, 0, arg1);
36     PyTuple_SetItem(args, 1, arg2);
37     PyObject* pValue = PyObject_CallObject(func, args);
38     if (pValue != NULL)
39     {
40         printf("Result of call: %ld\n", PyLong_AsLong(pValue));
41         Py_DECREF(pValue);
42     }
43     else
44     {
45         Py_DECREF(func);
46         Py_DECREF(pModule);
47         PyErr_Print();
48         fprintf(stderr, "Call failed\n");
49         return 1;
50     }
51     Py_Finalize();
52     system("pause");
53     return 0;
54 }

參考

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

https://www.cnblogs.com/yanzi-meng/p/8066944.html

C++程序調用python3