注:爲了方便,我把我在這個過程中的一些問題列在列下面,有很多bug的解決還是能在下面找到答案,希望能幫到你們。
鑑於博主我比較菜,所以這篇博客其實是建議如果要用C++調用還是Python2吧。當然可能一段時間以後有比較好的解決辦法或者python3變得更科學,或者你們知道很好的思路,歡迎評論區交流。
1. 配置
- 項目–>屬性–>vc++目錄–>包含目錄 添加python安裝目錄中include目錄
- 項目–>屬性–>vc++目錄–>庫目錄
- 添加python安裝目錄中libs目錄 鏈接器–>輸入–>附加依賴項 添加python35.lib
2. 在C++中調用python(版本3.5)
準備參考以下做,但是這些都是C++調用python2
C++ 調用 python
C++中嵌入python程序——使用API接口,從函數到類然後找到了這篇文章,但是裏面不涉及類,只有簡單的函數調用
c++與Python3互相調用在貼吧裏找到的回覆是這樣的
手冊裏是建議這樣產生一個類: https://docs.python.org/3/extending/newtypes.html
另外一種方式是調用PyType_Type這個對象來產生一個實例,也是個類來的…
來源:問題鏈接:http://bbs.csdn.net/topics/390748303
對的,有手冊當然是看手冊。在手冊裏好像可以發現新大陸的樣子。但是後來我發現,還是找不到關於Import class的東西
Extending Python with C or C++‘下面這個是之前被忽略的一篇文章,因爲標題總讓我以爲是在Python裏調用C++。文裏的一句話到了心坎上“有什麼問題記得多查英文資料,國內的這方面知識少”。
Python嵌入C++詳解(3)–Import Class
報錯:
找不到python35_d.lib這個文件。
思路:在pyconfig.h中把pragma comment(lib,"python35_d.lib")改成pragma comment(lib,"python35.lib")
發現還是報錯。
解決:還是乖乖用源碼編譯生成吧。
Python.org 下載源碼包
地址:https://www.python.org/downloads/source/
選擇 Gzipped source tarball
打開pcbuild目錄下的sln文件,必須用VS打開該解決方案,過低版本的vs打不開該解決方案。(sln用記事本打開裏面記着VS版本要求)
運行debug版本程序後,在pcbulid的win32文件夾裏能找到python35_d.lib
報錯:Py_Initialize: unable to load the file system codec
參考鏈接:http://stackoverflow.com/questions/5694706/py-initialize-fails-unable-to-load-the-file-system-codec
懶得認真讀貼的小朋友們可以參考從C調用Python腳本unableto load the file system codec ImportError錯誤解決方法
Import Fail
import module後,pMoule爲NULL
代碼:
PyObject* pModule = NULL;
PyObject* fname = PyUnicode_FromString("GameState");
pModule = PyImport_Import(fname);//GameState:Python文件名
或
PyObject* pModule = NULL;
pModule = PyImport_ImportModule("GameState");//GameState:Python文件名
用PyErr_Print()打印錯誤
代碼
PyObject* pModule = NULL;
//PyObject* fname = PyUnicode_FromString("GameState");
//pModule = PyImport_Import(fname);//GameState:Python文件名
pModule = PyImport_ImportModule("GameState");//GameState:Python文件名
if (pModule == nullptr)
{
PyErr_Print();
std::exit(1);
}
結果:
File "...\Debug\GameState.py", line 64
print 'Fail to write result.txt'
^
SyntaxError: Missing parentheses in call to 'print'
這個是由於python3的是print(“”),必須加括號。
修復這個bug:把源代碼中的print加上括號後,報錯信息
Traceback (most recent call last):
File "...\Debug\GameState.py", line 1, in <module>
from layout import Layout
File "...\Debug\layout.py", line 15, in <module>
import numpy as np
ImportError: No module named 'numpy'
爲了解決這個問題,去安裝numpy
見博客中文章numpy安裝
安裝完成之後新的報錯信息:
Traceback (most recent call last):
File "C:\Users\siyu\AppData\Local\Programs\Python\Python35\lib\site-packages\numpy\core\__init__.py", line 16, in <module>
from . import multiarray
ImportError: cannot import name 'multiarray'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\大三下\人工智能導論\SearchProject\mazemfc\Debug\GameState.py", line 1, in <module>
from layout import Layout
File "D:\大三下\人工智能導論\SearchProject\mazemfc\Debug\layout.py", line 15, in <module>
import numpy as np
File "C:\Users\siyu\AppData\Local\Programs\Python\Python35\lib\site-packages\numpy\__init__.py", line 142, in <module>
from . import add_newdocs
File "C:\Users\siyu\AppData\Local\Programs\Python\Python35\lib\site-packages\numpy\add_newdocs.py", line 13, in <module>
from numpy.lib import add_newdoc
File "C:\Users\siyu\AppData\Local\Programs\Python\Python35\lib\site-packages\numpy\lib\__init__.py", line 8, in <module>
from .type_check import *
File "C:\Users\siyu\AppData\Local\Programs\Python\Python35\lib\site-packages\numpy\lib\type_check.py", line 11, in <module>
import numpy.core.numeric as _nx
File "C:\Users\siyu\AppData\Local\Programs\Python\Python35\lib\site-packages\numpy\core\__init__.py", line 24, in <module>
raise ImportError(msg)
ImportError:
Importing the multiarray numpy extension module failed. Most
likely you are trying to import a failed build of numpy.
If you're working with a numpy git repo, try `git clean -xdf` (removes all
files not under version control). Otherwise reinstall numpy.
在這個bug之後就沒有再繼續玩下去的慾望了,換了python2.7天下太平,什麼事情都沒有發生。找了一些論壇和博客也沒看到此外的好的解決辦法,希望懂的大神們可以告知。
函數說明:
PyObject* PyObject_GetAttrString( PyObject *o, char *attr_name)
返回模塊對象o中的attr_name 屬性或函數,相當於Python中表達式語句:o.attr_name。例:
/* to call mymod.transform(mymod.message) */
pfunc = PyObject_GetAttrString(pmod, “transform”);
PyEval_CallObject(PyObject* pfunc, PyObject* pargs)
此函數有兩個參數,都指向Python對象指針,pfunc是要調用的Python 函數,通常可用PyObject_GetAttrString()獲得;pargs是函數的參數列表,通常可用Py_BuildValue()構建。例:
pstr = PyEval_CallObject(pfunc, pargs);
PyArg_Parse(pstr, “s”, &cstr);
printf(“%s\n”, cstr);
PyObject_CallObject和 PyEval_CallObject不同之處:
可以看出,後者較爲直接,而且接受NULL,and does explicit type checks
for args and kwds.
PyObject_CallObject(PyObject *o, PyObject *a)
{
! PyObject *r;
! PyObject *args = a;
!
! if (args == NULL) {
! args = PyTuple_New(0);
! if (args == NULL)
! return NULL;
! }
!
! r = PyEval_CallObject(o, args);
!
! if (args != a) {
! Py_DECREF(args);
! }
!
! return r;
}
PyObject_CallObject(PyObject *o, PyObject *a)
{
! return PyEval_CallObjectWithKeywords(o, a, NULL);
}
*/