我正在处理一个 SystemC 项目,我想使用 PyBind11 添加 python 绑定(bind),我一直在关注网站上的文档 here编写绑定(bind)。
我正在使用 CMake 构建我的项目,我面临的挑战是我需要将我的 C++ 代码链接到 SystemC 以及 PyBind11。这是我的 CMakeLists 当前的样子:
project(simple_fifo_python)
cmake_minimum_required(VERSION 3.0)
find_package(pybind11 CONFIG REQUIRED)
message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
find_library(SC_LIB systemc $ENV{SYSTEMC_HOME}/lib-linux64 REQUIRED)
pybind11_add_module (simple_fifo_python simple_fifo.cpp)
target_compile_options(simple_fifo_python PUBLIC -Wall)
target_include_directories(simple_fifo_python PUBLIC $ENV{SYSTEMC_HOME}/include)
target_link_libraries(simple_fifo_python PUBLIC ${SC_LIB})
我的代码是这样编译的:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <systemc.h>
class write_if : virtual public sc_interface
{
public:
virtual void write(char) = 0;
virtual void reset() = 0;
};
class read_if : virtual public sc_interface
{
public:
virtual void read(char &) = 0;
virtual int num_available() = 0;
};
class fifo : public sc_channel, public write_if, public read_if
{
public:
fifo(sc_module_name name) : sc_channel(name), num_elements(0), first(0) {}
void write(char c) {
if (num_elements == max)
wait(read_event);
data[(first + num_elements) % max] = c;
++ num_elements;
write_event.notify();
}
void read(char &c){
if (num_elements == 0)
wait(write_event);
c = data[first];
-- num_elements;
first = (first + 1) % max;
read_event.notify();
}
void reset() { num_elements = first = 0; }
int num_available() { return num_elements;}
private:
enum e { max = 10 };
char data[max];
int num_elements, first;
sc_event write_event, read_event;
};
class producer : public sc_module
{
public:
sc_port<write_if> out;
SC_HAS_PROCESS(producer);
producer(sc_module_name name) : sc_module(name)
{
SC_THREAD(main);
}
void main()
{
const char *str =
"This can really work with pybind11 yo peeepalsssssss!\n";
while (*str)
out->write(*str++);
}
};
class consumer : public sc_module
{
public:
sc_port<read_if> in;
SC_HAS_PROCESS(consumer);
consumer(sc_module_name name) : sc_module(name)
{
SC_THREAD(main);
}
void main()
{
char c;
cout << endl << endl;
while (true) {
in->read(c);
cout << c << flush;
if (in->num_available() == 1)
cout << "<1>" << flush;
if (in->num_available() == 9)
cout << "<9>" << flush;
}
}
};
class top : public sc_module
{
public:
fifo *fifo_inst;
producer *prod_inst;
consumer *cons_inst;
top(sc_module_name name) : sc_module(name)
{
fifo_inst = new fifo("Fifo1");
prod_inst = new producer("Producer1");
prod_inst->out(*fifo_inst);
cons_inst = new consumer("Consumer1");
cons_inst->in(*fifo_inst);
}
};
int sc_main (int, char *[]) {
top top1("Top1");
sc_start();
return 0;
}
namespace py = pybind11;
using namespace pybind11::literals;
PYBIND11_MODULE(test, m)
{
m.doc() = "pybind11 test plugin with sysc support"; // optional module docstring
py::class_<fifo>(m, "fifo")
.def(py::init<sc_module_name>())
.def("write", &fifo::write)
.def("read", &fifo::read)
.def("reset", &fifo::reset)
.def("num_available", &fifo::num_available)
.def_property("num_elements", &fifo::reset, &fifo::num_available);
py::class_<producer>(m, "producer")
.def(py::init<sc_module_name>())
.def("main", &producer::main);
py::class_<consumer>(m, "consumer")
.def(py::init<sc_module_name>())
.def("main", &consumer::main);
py::class_<top>(m, "top")
.def(py::init<sc_module_name>());
m.def("sc_main", [](std::vector<std::string> args)
{
std::vector<char *> cstrs;
cstrs.reserve(args.size());
for (auto &s : args) cstrs.push_back(const_cast<char *>(s.c_str()));
return sc_main(cstrs.size(), cstrs.data());
});
}
我正在按照 cmake_example repository 进行编译并且 pip 命令成功运行并生成了我可以导入的轮子。 但是,当我运行 python 并尝试导入模块时,它失败并出现以下错误:
(py37) mayank@b101l:~/test/pybindmod/simple_fifo$ python
Python 3.7.1 (default, Oct 23 2018, 19:19:42)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import simple_fifo_python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /home/mayank/tools/lib-linux64/libsystemc-2.3.2.so: undefined symbol: sc_main
>>>
这是我使用具有多个依赖项的 PyBind 和 CMakeLists 的第一个项目,所以我不知道这个错误是从哪里来的。任何帮助将不胜感激。
最佳答案
这是因为 SystemC 共享库需要 sc_main
函数。
您应该尝试链接静态库(libsystemc-2.3.2.a
)。
关于c++ - PyBind11 与 SystemC 使用 CMake : ImportError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53369920/