Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
hsz1273327 committed Dec 12, 2023
1 parent 084fb1d commit 6920de0
Show file tree
Hide file tree
Showing 10 changed files with 615 additions and 40 deletions.
Binary file modified 与Python交互/C中调用Python模块/.DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
gcc -I /Users/mac/micromamba/envs/py3.10/include/python3.10 -L/Users/mac/micromamba/envs/py3.10/lib -lpython3.10 -o helloworld main.c
g++ -I /Users/mac/micromamba/envs/py3.10/include/python3.10 -L/Users/mac/micromamba/envs/py3.10/lib -lpython3.10 -o helloworld.o -std=c++20 -c helloworld.cpp
g++ -I /Users/mac/micromamba/envs/py3.10/include/python3.10 -L/Users/mac/micromamba/envs/py3.10/lib -lpython3.10 -o helloworld_wrap.o -std=c++20 -c helloworld_wrap.cpp
g++ -I /Users/mac/micromamba/envs/py3.10/include/python3.10 -L/Users/mac/micromamba/envs/py3.10/lib -lpython3.10 -o main.o -std=c++20 -c main.cpp


g++ -I /Users/mac/micromamba/envs/py3.10/include/python3.10 -L/Users/mac/micromamba/envs/py3.10/lib -lpython3.10 -std=c++20 *.o -o helloworld




g++ -I /Users/mac/micromamba/envs/py3.10/include/python3.10 -L/Users/mac/micromamba/envs/py3.10/lib -lpython3.10 -o helloworld -std=c++20 helloworld.cpp helloworld_wrap.cpp main.cpp


gcc *.c -o
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int numargs = 0;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@


/* $Id$ */
#ifndef HELLOWORLD_H
#define HELLOWORLD_H//一般是文件名的大写 头文件结尾写上一行

int numargs;

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "helloworld.h"
/* Return the number of arguments of the application command line */
static PyObject* emb_numargs(PyObject* self, PyObject* args) {
if (!PyArg_ParseTuple(args, ":numargs"))
return NULL;
return PyLong_FromLong(numargs);
}

static PyMethodDef EmbMethods[] = {{"numargs", emb_numargs, METH_VARARGS, "Return the number of arguments received by the process."}, {NULL, NULL, 0, NULL}};

static PyModuleDef EmbModule = {PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods, NULL, NULL, NULL, NULL};

static PyObject* PyInit_emb(void) {
return PyModule_Create(&EmbModule);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* $Id$ */
#ifndef HELLOWORLD_WRAP_H
#define HELLOWORLD_WRAP_H

#define PY_SSIZE_T_CLEAN
#include <Python.h>

// static PyObject* emb_numargs(PyObject* self, PyObject* args);
// static PyMethodDef EmbMethods[];
// static PyModuleDef EmbModule;
static PyObject* PyInit_emb(void);

#endif
39 changes: 0 additions & 39 deletions 与Python交互/C程序中嵌入python解释器/helloworld/main.c

This file was deleted.

132 changes: 132 additions & 0 deletions 与Python交互/C程序中嵌入python解释器/helloworld/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <exception>
#include <filesystem>
#include "helloworld.h"
#include "helloworld_wrap.h"
#include "scope_guard.hpp"

class AppException : public std::runtime_error {
public:
AppException(const char* err) : std::runtime_error(err) {}
};

void init_py(char* programname, char* envpath, char* pymodulepath, bool debugmod) {
wchar_t* program;
wchar_t* env_dir_name;
wchar_t* pymodule_dir_name;
program = Py_DecodeLocale(programname, NULL);
if (program == NULL) {
throw AppException("Fatal error: cannot decode programname");
}

// 初始化python设置
PyStatus status;
PyConfig config;
PyConfig_InitPythonConfig(&config);
auto guard = sg::make_scope_guard([&config]() noexcept {
PyConfig_Clear(&config);
printf("python init config clear\n");
});

// 设置python程序名
status = PyConfig_SetString(&config, &config.program_name, program);
if (PyStatus_Exception(status)) {
throw AppException("Fatal error: InitPythonConfig set program_name get error");
}
// 加载默认配置
status = PyConfig_Read(&config);
if (PyStatus_Exception(status)) {
throw AppException("Fatal error: PyConfig_Read get error");
}
// 设置python的sys.path用于查找模块
std::filesystem::path pymodule_dir;
if (pymodulepath == NULL) {
pymodule_dir = std::filesystem::current_path();
} else {
pymodule_dir = pymodulepath;
if (pymodule_dir.is_relative()) {
pymodule_dir = std::filesystem::absolute(pymodule_dir);
}
}
auto _pymodule_dir_name = pymodule_dir.string().c_str();
pymodule_dir_name = Py_DecodeLocale(_pymodule_dir_name, NULL);
if (pymodule_dir_name == NULL) {
throw AppException("Fatal error: cannot decode pymodule_dir_name");
} else {
if (debugmod) {
printf("pymodule_dir %s \n", _pymodule_dir_name);
}
}
config.module_search_paths_set = 1;
status = PyWideStringList_Append(&config.module_search_paths, pymodule_dir_name);
if (PyStatus_Exception(status)) {
throw AppException("Fatal error: InitPythonConfig set module_search_paths get error");
}

// 设置虚拟环境
if (envpath != NULL) {
std::filesystem::path env_dir = envpath;
if (env_dir.is_relative()) {
env_dir = std::filesystem::absolute(env_dir);
}
auto _env_dir_name = env_dir.string().c_str();
env_dir_name = Py_DecodeLocale(_env_dir_name, NULL);
if (env_dir_name == NULL) {
throw AppException("Fatal error: cannot decode _env_dir_name");
} else {
if (debugmod) {
printf("use virtual environments %s \n", _env_dir_name);
}
}
status = PyConfig_SetString(&config, &config.prefix, env_dir_name);
if (PyStatus_Exception(status)) {
throw AppException("Fatal error: InitPythonConfig set prefix get error");
}
status = PyConfig_SetString(&config, &config.exec_prefix, env_dir_name);
if (PyStatus_Exception(status)) {
throw AppException("Fatal error: InitPythonConfig set exec_prefix get error");
}
}
// 提前初始化模块`emb`
numargs = 10;
PyImport_AppendInittab("emb", &PyInit_emb);

status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status)) {
if (PyStatus_IsExit(status)) {
// return status.exitcode;
throw AppException("Fatal error: PyStatus_IsExit");
}
// 抛出错误
Py_ExitStatusException(status);
}
PyMem_RawFree(pymodule_dir_name);
if (envpath != NULL) {
PyMem_RawFree(env_dir_name);
}
PyMem_RawFree(program);
if (debugmod) {
PyRun_SimpleString("import sys;print(sys.path);print(sys.prefix)");
}
}

int finalize_py() {
if (Py_FinalizeEx() < 0) {
return 120;
}
printf("finalize_py ok\n");
return 0;
}

int main(int argc, char* argv[]) {
// 初始化python解释器
try {
init_py(argv[0], "env/", NULL, false);
PyRun_SimpleString("import emb;print('Number of arguments', emb.numargs())");
} catch (const AppException& ex) {
fprintf(stderr, ex.what());
return 1;
}
return finalize_py();
}
Loading

0 comments on commit 6920de0

Please sign in to comment.