如何用Python包装C++库(.h与.lib文件)?

3 投票
1 回答
581 浏览
提问于 2025-04-18 02:47

我有一个C++的库,里面只有 .h.lib 文件(没有 .cpp 文件),这个库是用来和某个硬件进行通信的,我需要在Python中使用这个库。由于我对C/C++的了解不多,所以这些东西对我来说有点陌生。

这些 .h 文件大概长这样:

#define MSG_DLL_VERSION 10

typedef struct {
   ULONG ulDLLVersion;
   // vipmsg variables
   PMSGACCOUNTS pMsgAccounts;
   PMSGSEGMENT  pMsgSegment;
   USHORT       usMsgSegmentNum;
} MSGSTATICDATA, *PMSGSTATICDATA;

VOID msgGetDLLRedirections ( PMSGSTATICDATA *pData ); 

VOID msgSetDLLRedirections ( PMSGSTATICDATA pData ); 

我查了一下,发现了一些信息:

  • Cython主要是为了C语言。它 可以 处理C++,但需要 .cpp 文件
  • Boost.Python也需要 .cpp 文件
  • cffi只支持C语言
  • ctypes也只支持C语言

那么,最好的解决办法是什么呢?

1 个回答

1

Boost.Python 也需要 .cpp 文件

其实并不是。你可以用 Boost.Python 来包装你的库。使用 Boost.Python 来暴露 C++ 代码的方法是,利用 Boost.Python 提供的各种宏来写一个共享库。

Boost.Python 的文档展示了如何包装这个 C++ 类型:

struct World
{
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};

这个包装器看起来是这样的:

#include <boost/python.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World")
        .def("greet", &World::greet)
        .def("set", &World::set)
    ;
}

你可以用你的库来做这个。你确实需要写这个包装器。但是,包装的类和方法是定义在 .lib 库文件中,而不是 .cpp 源文件,这个并不重要。


更新

从头文件的示例代码来看,这更像是一个 C 风格的库,而不是 C++。你当然可以使用 Boost.Python 来处理这个。SWIG 也是一个选择,或者你可以用 ctypes。

撰写回答