在c+中使用python obj+;使用pybind和多处理
我尝试使用pybd11和AM来实现一个C++到python。不同之处在于,我想在C++中使用Python对象,并从C++中继续调用类方法。代码如下:在c+中使用python obj+;使用pybind和多处理,python,c++,multiprocessing,pybind11,Python,C++,Multiprocessing,Pybind11,我尝试使用pybd11和AM来实现一个C++到python。不同之处在于,我想在C++中使用Python对象,并从C++中继续调用类方法。代码如下: #ifdef _WIN32 #include "direct.h" #define PATH_SEP '\\' #define GETCWD _getcwd #define CHDIR _chdir #else #include "unistd.h" #define PATH_SEP '/' #define GETCWD getcwd #defin
#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
using namespace py::literals;
bool ChangeDirectory(const char* dir) { return CHDIR(dir) == 0; }
int wmain(int argc, wchar_t** argv)
{
py::initialize_interpreter();
PySys_SetArgv(argc, argv);
std::string pyCode = std::string(R"(
import os
import sys
from queue import Empty, Full
from multiprocessing import Queue as mQueue, Process as mProcess
import sys
sys.executable = "C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe"
__file__ = "D:\\sw\\run.py"
print("Hello stackoverflow!", file=open("output.txt", "a"))
class C2PyMulti(object):
"""docstring for TactileEngine"""
def __init__(self):
self.te_ops = MultiProcessTest()
def compose(self,data):
self.te_ops.load_q(data)
class MultiProcessTest(object):
def __init__(self):
self.my_q = mQueue()
self.spawn_processes()
def load_q(self, data):
self.my_q.put(('print',data))
def spawn_processes(self):
args = (self.my_q,'inside message_coordinator')
self.message_coordinator = mProcess(target=message_coordinator, args=args)
try:
# Starts the data processor
val = self.message_coordinator.start()
if val == 1:
self.message_coordinator.join()
except Exception:
print('failed spawn!')
def message_coordinator(mQ,num):
print(num)
while True:
try:
command, args= mQ.get(timeout=.0001)
if command == 'print':
print(args, file=open("output.txt", "a"))
elif command == 'end':
return 1
except (Empty):
pass
cpy2 = C2PyMulti()
cpy2.compose('hello')
cpy2.compose('hello')
cpy2.compose('hello')
cpy2.compose('hello')
cpy2.compose('end')
del cpy2
)");
try
{
FILE* f = nullptr;
fopen_s(&f, "D:\\sw\\run.py", "wt");
fprintf(f, "%s", pyCode.c_str());
fclose(f);
ChangeDirectory("D:\sw\run.py");
//py::module C2py = py::module::import("run"); ///does not work can't find the module
//py::object C2PyMulti = C2py.attr("C2PyMulti");
//py::object c2py = C2PyMulti();
//c2py.attr("load_q")("hello");
py::exec(pyCode);
}
catch (const std::exception & e) {
std::cout << e.what();
}
py::finalize_interpreter();
}
最后,我想使用类似于以下内容的内容:
py::module C2py = py::module::import("C2PyMulti");
py::object C2PyMulti = C2py.attr("C2PyMulti");
py::object c2py = C2PyMulti();
c2py.attr("load_q")("hello");
我的预约提前了。所以要回答这个问题,我需要分离消息协调器方法,并通过另一个线程调用它,如:
void message(py::module C2py, py::object queue) {
py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}
并通过std::thread ti(message,C2py,q)调用它代码>因此最终结果是:
#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>
#include <thread>
namespace py = pybind11;
using namespace py::literals;
bool ChangeDirectory(const char* dir) { return CHDIR(dir) == 0; }
void message(py::module C2py, py::object queue) {
py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}
int wmain(int argc, wchar_t** argv)
{
py::initialize_interpreter();
PySys_SetArgv(argc, argv);
std::string pyCode = std::string(R"(
import os
import sys
from queue import Empty, Full
from multiprocessing import Queue as mQueue, Process as mProcess
import sys
sys.executable = "C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe"
__file__ = "D:\\sw\\run.py"
print("Start of module!")
class C2PyMulti(object):
"""docstring for TactileEngine"""
def __init__(self):
pass
def build(self):
return MultiProcessTest()
def compose(self,te_ops, data):
te_ops.load_q(data)
class MultiProcessTest(object):
def __init__(self):
print("Start of MultiProcessTest!")
#self.spawn_processes()
def build_q(self):
self.my_q = mQueue()
return self.my_q
def load_q(self, data):
self.my_q.put(('print',data))
def spawn_processes(self):
args = (self.my_q,'Inside message_coordinator')
self.message_coordinator = mProcess(target=message_coordinator, args=args)
try:
# Starts the data processor
self.message_coordinator.start()
except Exception:
print('failed spawn!')
def message_coordinator(mQ,num):
print(num)
while True:
try:
command, args= mQ.get(timeout=.0001)
if command == 'print':
print("command: {}, args: {}".format(command,args))
elif command == 'end':
print("command: {}, args: {}".format(command,args))
except (Empty):
pass
)");
try
{
FILE* f = nullptr;
fopen_s(&f, "D:\\sw\\run.py", "wt");
fprintf(f, "%s", pyCode.c_str());
fclose(f);
ChangeDirectory("D:/sw");
py::module C2py = py::module::import("run");
py::object C2PyMulti = C2py.attr("C2PyMulti");
py::object c2py = C2PyMulti();
py::object c2pybuild = c2py.attr("build");
py::object b = c2pybuild();
py::object q = b.attr("build_q")();
py::object compose = c2py.attr("compose");
compose(b, "fromoutside");
compose(b, "fromoutside2");
compose(b, "fromoutside3");
compose(b, "fromoutside4");
compose(b, "fromoutside5");
compose(b, "fromoutside6");
compose(b, "fromoutside7");
compose(b, "fromoutside8");
std::thread ti(message, C2py, q);
compose(b, "fromoutside9");
compose(b, "fromoutside10");
b.attr("load_q")("hello4");
b.attr("load_q")("hello5");
b.attr("load_q")("hello6");
while (true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
//py::exec(pyCode);
}
catch (const std::exception & e) {
std::cout << e.what();
}
py::finalize_interpreter();
}
\ifdef\u WIN32
#包括“direct.h”
#定义路径\u SEP'\\'
#定义GETCWD\u GETCWD
#定义CHDIR\u CHDIR
#否则
#包括“unistd.h”
#定义路径_SEP'/'
#定义GETCWD GETCWD
#定义CHDIR CHDIR
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
名称空间py=pybind11;
使用名称空间py::literals;
bool ChangeDirectory(const char*dir){return CHDIR(dir)==0;}
无效消息(py::模块C2py,py::对象队列){
对象消息协调器=C2py.attr(“消息协调器”)(队列,“在消息协调器中!”);
}
内部wmain(内部argc,wchar\u t**argv)
{
py::初始化_解释器();
PySys_SetArgv(argc,argv);
std::string pyCode=std::string(R)(
导入操作系统
导入系统
从队列导入空、满
从作为MQUE的多处理导入队列,将进程作为MPPROCESS
导入系统
sys.executable=“C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe”
__文件
打印(“模块开始!”)
类C2PyMulti(对象):
“”“TactileEngine的文档字符串”“”
定义初始化(自):
通过
def生成(自):
返回多进程测试()
def合成(自身、TEU操作、数据):
te_ops.load_q(数据)
类多进程测试(对象):
定义初始化(自):
打印(“开始多进程测试!”)
#self.spawn_进程()
def build_q(自我):
self.my_q=mQueue()
返回self.my_q
def加载_q(自身,数据):
self.my_q.put((‘打印’,数据))
def生成_进程(自身):
args=(self.my_q,“内部消息协调器”)
self.message\u coordinator=MPProcess(目标=message\u coordinator,args=args)
尝试:
#启动数据处理器
self.message\u coordinator.start()
除例外情况外:
打印('failed spawn!')
def消息协调器(mQ,num):
打印(个)
尽管如此:
尝试:
命令,args=mQ.get(超时=0.0001)
如果命令=='print':
打印(“命令:{},参数:{}”。格式(命令,参数))
elif命令=='end':
打印(“命令:{},参数:{}”。格式(命令,参数))
除(空):
通过
)");
尝试
{
FILE*f=nullptr;
fopen_s&f,“D:\\sw\\run.py”,“wt”);
fprintf(f,“%s”,pyCode.c_str());
fclose(f);
变更目录(“D:/sw”);
py::module C2py=py::module::import(“运行”);
py::对象C2PyMulti=C2py.attr(“C2PyMulti”);
py::object c2py=C2PyMulti();
py::object c2pybuild=c2py.attr(“build”);
py::object b=c2pybuild();
对象q=b.attr(“构建q”)();
py::object compose=c2py.attr(“compose”);
撰写(b,“来自外部”);
撰写(b,“来自外部2”);
撰写(b,“来自外部3”);
撰写(b,“来自外部4”);
撰写(b,“外部5”);
撰写(b,“来自外部6”);
撰写(b,“来自外部7”);
撰写(b,“来自外部8”);
std::线程ti(消息,C2py,q);
撰写(b,“来自外部9”);
撰写(b,“外部10”);
b、 属性(“负载”)(“hello4”);
b、 属性(“负载”)(“hello5”);
b、 属性(“负载”)(“hello6”);
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
//py::exec(pyCode);
}
捕获(const std::exception&e){
std::cout所以要回答这个问题,我需要分离消息协调器方法,并通过另一个线程调用它,如:
void message(py::module C2py, py::object queue) {
py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}
并通过std::thread ti(message,C2py,q);
调用它,因此最终结果是:
#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>
#include <thread>
namespace py = pybind11;
using namespace py::literals;
bool ChangeDirectory(const char* dir) { return CHDIR(dir) == 0; }
void message(py::module C2py, py::object queue) {
py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}
int wmain(int argc, wchar_t** argv)
{
py::initialize_interpreter();
PySys_SetArgv(argc, argv);
std::string pyCode = std::string(R"(
import os
import sys
from queue import Empty, Full
from multiprocessing import Queue as mQueue, Process as mProcess
import sys
sys.executable = "C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe"
__file__ = "D:\\sw\\run.py"
print("Start of module!")
class C2PyMulti(object):
"""docstring for TactileEngine"""
def __init__(self):
pass
def build(self):
return MultiProcessTest()
def compose(self,te_ops, data):
te_ops.load_q(data)
class MultiProcessTest(object):
def __init__(self):
print("Start of MultiProcessTest!")
#self.spawn_processes()
def build_q(self):
self.my_q = mQueue()
return self.my_q
def load_q(self, data):
self.my_q.put(('print',data))
def spawn_processes(self):
args = (self.my_q,'Inside message_coordinator')
self.message_coordinator = mProcess(target=message_coordinator, args=args)
try:
# Starts the data processor
self.message_coordinator.start()
except Exception:
print('failed spawn!')
def message_coordinator(mQ,num):
print(num)
while True:
try:
command, args= mQ.get(timeout=.0001)
if command == 'print':
print("command: {}, args: {}".format(command,args))
elif command == 'end':
print("command: {}, args: {}".format(command,args))
except (Empty):
pass
)");
try
{
FILE* f = nullptr;
fopen_s(&f, "D:\\sw\\run.py", "wt");
fprintf(f, "%s", pyCode.c_str());
fclose(f);
ChangeDirectory("D:/sw");
py::module C2py = py::module::import("run");
py::object C2PyMulti = C2py.attr("C2PyMulti");
py::object c2py = C2PyMulti();
py::object c2pybuild = c2py.attr("build");
py::object b = c2pybuild();
py::object q = b.attr("build_q")();
py::object compose = c2py.attr("compose");
compose(b, "fromoutside");
compose(b, "fromoutside2");
compose(b, "fromoutside3");
compose(b, "fromoutside4");
compose(b, "fromoutside5");
compose(b, "fromoutside6");
compose(b, "fromoutside7");
compose(b, "fromoutside8");
std::thread ti(message, C2py, q);
compose(b, "fromoutside9");
compose(b, "fromoutside10");
b.attr("load_q")("hello4");
b.attr("load_q")("hello5");
b.attr("load_q")("hello6");
while (true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
//py::exec(pyCode);
}
catch (const std::exception & e) {
std::cout << e.what();
}
py::finalize_interpreter();
}
\ifdef\u WIN32
#包括“direct.h”
#定义路径\u SEP'\\'
#定义GETCWD\u GETCWD
#定义CHDIR\u CHDIR
#否则
#包括“unistd.h”
#定义路径_SEP'/'
#定义GETCWD GETCWD
#定义CHDIR CHDIR
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
名称空间py=pybind11;
使用名称空间py::literals;
bool ChangeDirectory(const char*dir){return CHDIR(dir)==0;}
无效消息(py::模块C2py,py::对象队列){
对象消息协调器=C2py.attr(“消息协调器”)(队列,“在消息协调器中!”);
}
内部wmain(内部argc,wchar\u t**argv)
{
py::初始化_解释器();
PySys_SetArgv(argc,argv);
std::string pyCode=std::string(R)(
导入操作系统
导入系统
从队列导入空、满
从作为MQUE的多处理导入队列,将进程作为MPPROCESS
导入系统
sys.executable=“C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe”
__文件
打印(“模块开始!”)
类C2PyMulti(对象):
“”“TactileEngine的文档字符串”“”
定义初始化(自):
通过
def生成(自):
返回多进程测试()
def合成(自身、TEU操作、数据):
te_ops.load_q(数据)
类多进程测试(对象):
定义初始化(自):
打印(“开始多进程测试!”)
#self.spawn_进程()
def build_q(自我):
self.my_q=mQueue()
返回self.my_q
def加载_q(自身,数据):
self.my_q.put((‘打印’,数据))
def生成_进程(自身):
args=(self.my_q,“内部消息协调器”)
self.message\u coordinator=MPProcess(目标=message\u coordinator,args=args)
尝试:
#启动数据处理器
self.message\u coordinator.start()
除例外情况外:
打印('failed spawn!')
def消息协调器(mQ,num):
打印(个)