PyBind11 with SystemC using CMake: ImportError



我正在处理一个SystemC项目,我想使用PyBind11将python绑定添加到该项目中,并且我一直在遵循网站上的文档来编写绑定
我正在使用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存储库编译的,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++篡改了sc_main符号,systemc库需要并期望使用C符号格式。你能试着在sc_main之前添加一个extern "C"吗?类似的东西

extern "C" int sc_main (int, char *[]) {
top top1("Top1");
sc_start();
return 0;
}

将函数sc_main移动到一个单独的*.c文件中。

最新更新