c++ - PyBind11 与 SystemC 使用 CMake : ImportError

标签 c++ python-3.x cmake systemc pybind11

我正在处理一个 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/

相关文章:

c++ - CMake 生成的带有系统和标准的 c++ 项目包括

visual-studio - QT构建因NMAKE : fatal error U1077: 'echo' : return code '0x1' 而失败

c++ - 基类中的数据成员出现在派生类中是否会导致内存浪费?

c++ - 如何从 unsigned char* 获取 Qstring?

django - 如何在 django 中正确地乘以查询集中的值

Python3 查找字符串的 crc32

cmake - 如果 Cmake find_package 找不到包,如何提供自定义错误消息?

c++ - 外部模板和不完整类型

c++ - 如何提取opencv Mat header ?

python - 阿姆斯特朗/自恋数字,以 16 为底/十六进制