Windows环境下用C++语言调用Python程序

按照网上教程编写Python代码hello.py如下

def printHello():
    print("Hello World")

if __name__ == "__main__":
    printHello()

写c++代码main.cpp如下(和上述Python代码在同一目录下):

#include <iostream>
#include <vector>
#include <string>
#include <Python.h>

using namespace std;

void cython1(){
    Py_Initialize();       //初始化python解释器,告诉编译器要用的python编译器
    PyRun_SimpleString("import hello");  //调用python文件
    PyRun_SimpleString("hello.printHello()"); //调用上述文件中的函数
    Py_Finalize();       //结束python解释器,释放资源
}
 
void cython2(){
    Py_Initialize();
    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    pModule = PyImport_ImportModule("hello");    //这里是要调用的文件名
    pFunc = PyObject_GetAttrString(pModule, "printHello"); //这里是要调用的函数名
    PyEval_CallObject(pFunc, NULL);      //调用函数
    Py_Finalize();
}
 
int main(){
    int select;
    cin >> select;
    select == 1 ? cython1():cython2();
    return 0;
}

刚开始打算用VSCode自带的c_cpp_properties.json中配置编译后失败,这里includePath为python虚拟环境的include目录,并需要包括libs

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "D:/Program Files/Anaconda3/envs/tensorflow/include"
            ],
            "browse": {
                "path": [
                    "${workspaceRoot}",
                    "D:/Program Files/Anaconda3/envs/tensorflow/libs"
                ]
            },
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "D:\\cygwin64\\bin\\gcc.exe",
            "cStandard": "gnu11",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

后决定安装mingw-64-gcc8.1.0,通过g++命令直接编译(机器已安装cygwin64安装mingw-64后卸载),其中报错主要有:

1报错找不到include 的python.h文件
找到python.h所在的目录
比如:C:\ProgramData\Anaconda3\include
编译时添加 -I C:\ProgramData\Anaconda3\include
g++找到了python.h

g++ -I C:\ProgramData\Anaconda3\include test.cpp


2报错’::hypot’ has not been declared"error in g++”

在stackoverflow中,找到答案
https://stackoverflow.com/questions/42276984/hypot-has-not-been-declared

修改mingw目录中cmath文件 (C:/mingw64/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/cmath:1121:11)
改变为:

using ::_hypot;
//本人采用该方法

或者修改python虚拟环境include中pyconfig.h的241行

#define hypot _hypot

改为

#define hypot hypot

3报错 undefined reference to “__imp_PyTuple_New”
或 undefined reference to “__imp_Py_Initialize()”
解决办法是先找到gendef.exe,在mingw-64的bin目录下,比如C:\TDM-GCC-64\x86_64-w64-mingw32\bin
加入环境变量,我的电脑->propertise->advanced system setting->Enviroment Variables->User variables->Path->edit->
测试,gendef命令可用(这是为什么采用mingw64而不是cygwin的原因cygwin64没有该命令)
然后进入Python虚拟环境中python36.dll所在的目录,生成def,方法如下:

参考https://stackoverflow.com/questions/6731100/link-to-python-with-mingw
Try this…
1)Download gendef for your version of mingw (32 or 64 bit), and in msys shell…
2)Run gendef python36.dll
3)Run dlltool -D python36.dll -d python36.def -l libpython36.a
4)Copy libpython36.a to your ./python36/libs directory.

此时,在c++目录下运行

g++ -I "D:\Program Files\Anaconda3\envs\tensorflow\include" -L "D:\Program Files\Anaconda3\envs\tensorflow\libs" main.cpp -lpython36

即可生成a.exe文件

还需注意

python - 将Python嵌入C: undefined reference (但在Go中可用) - IT工具网 (coder.work)

参数main.cpp必须放在-lpython37之前的某处。

所以这有效:

gcc "-IC:/Program Files/Python37_64/include" "-LC:/Program Files/Python37_64/libs" main.c -lpython37 
//本人命令如下
g++ -I "D:\Program Files\Anaconda3\envs\tensorflow\include" -L "D:\Program Files\Anaconda3\envs\tensorflow\libs" main.cpp -lpython36

至此就学会如何使用C调用python程序了!后续Linux下C调用Python程序思路类似!
 

posted @ 2022-01-08 19:53  Mr.zzz  阅读(726)  评论(0编辑  收藏  举报