window
c调用python的原理大概是将python当做一个c++库来调用
导入头文件
将python的头文件复制到项目中,头文件在python安装目录中
在vs项目属性中的vc++目录的包含目录添加头文件路径
导入库文件
库文件在python安装目录的libs文件夹中
在vs项目属性中的vc++目录的库目录添加库文件所在文件路径
添加附加依赖项
python37.lib
python3.lib
python37_d.lib
添加二进制文件
需要的二进制文件有 python3*.dll、python3.dll、DLLs、Lib文件夹(注意Lib中的site-packages文件的第三方python库按实际需要增减)
使用api调用python代码
initializer.h
#pragma once
#include <Python.h>
#ifdef _WIN32
#include <Windows.h>
#elif defined __APPLE__
#endif
#include "utils.h"
class initializer {
public:
initializer() {
#ifdef _WIN32
#include <Windows.h>
SetDllDirectory(TEXT("python37\\"));
#elif defined __APPLE__
#endif
Py_SetPythonHome(string2wstring(get_executable_dir()).c_str());
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.argv.append('1')");
//PyRun_SimpleString("print(sys.path)");
}
~initializer() {
Py_Finalize();
}
};
utils.h
#include <iostream>
std::string get_executable_dir();
std::string wstring2string(const std::wstring& ws);
std::wstring string2wstring(const std::string& s);
utils_win.cpp
#include "utils.h"
#include <Windows.h>
#include <comutil.h>
using namespace std;
#pragma comment(lib , "comsupp.lib")
#pragma comment(lib , "comsuppw.lib")
std::string get_executable_dir() {
std::string exeDir = "";
char szExeName[MAX_PATH] = {0,};
volatile int lastIndex = 0;
::GetModuleFileNameA(NULL, szExeName, MAX_PATH);
exeDir = szExeName;
lastIndex = exeDir.find_last_of("\\") + 1;
exeDir = exeDir.substr(0, lastIndex);
return exeDir;
}
std::string wstring2string(const wstring& ws)
{
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
std::wstring string2wstring(const string& s)
{
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}
main.cpp
#include <iostream>
#include "initializer.h"
using namespace std;
initializer initer;
void call_main() {
char* result;
PyObject* pModule = PyImport_ImportModule("test");
Sleep(0);
if (pModule == NULL) {
PyErr_Print();
cout << "module not found" << endl;
return ;
}
PyObject* pFunc = PyObject_GetAttrString(pModule, "main");
if (!pFunc || !PyCallable_Check(pFunc)) {
PyErr_Print();
cout << "not found function init" << endl;
return ;
}
PyObject* pReturn = PyObject_CallObject(pFunc, NULL);
PyErr_Print();
}
void inputArgs(int argc, char** argv) {
PyRun_SimpleString((string("sys.argv[0] = '") + argv[0] + "'").c_str());
if(argc>1)
for (int i=1;i<argc;i++)
PyRun_SimpleString((string("sys.argv.append('")+argv[i]+"')").c_str());
}
int main(int argc,char ** argv)
{
inputArgs(argc, argv);
call_main();
return 0;
}
编译出exe后在当前目录建立test.py
test.py
def main():
print("hello world!")
将python3*.dll、python3.dll、DLLs、Lib文件夹放入exe当前目录即可执行成功
Macos
修改install_name
install_name_tool -change /Library/Frameworks/Python.framework/Versions/3.7/Python @loader_path/Python CPython++