C++調用python3

注:爲了方便,我把我在這個過程中的一些問題列在列下面,有很多bug的解決還是能在下面找到答案,希望能幫到你們。
鑑於博主我比較菜,所以這篇博客其實是建議如果要用C++調用還是Python2吧。當然可能一段時間以後有比較好的解決辦法或者python3變得更科學,或者你們知道很好的思路,歡迎評論區交流。

1. 配置

  1. 項目–>屬性–>vc++目錄–>包含目錄 添加python安裝目錄中include目錄
  2. 項目–>屬性–>vc++目錄–>庫目錄
  3. 添加python安裝目錄中libs目錄 鏈接器–>輸入–>附加依賴項 添加python35.lib

2. 在C++中調用python(版本3.5)

手冊裏是建議這樣產生一個類: 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);
}
*/

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