为啥我的由 boost.python 和 c++ 头文件编译的 .so 文件失败了?

Posted

技术标签:

【中文标题】为啥我的由 boost.python 和 c++ 头文件编译的 .so 文件失败了?【英文标题】:why my .so file which is complied by boost.python and c++ header file failed?为什么我的由 boost.python 和 c++ 头文件编译的 .so 文件失败了? 【发布时间】:2019-09-12 04:26:09 【问题描述】:

我基于我的 c++ 代码成功构建了一些 .so,让 python 调用。 但是对于这个,很奇怪,我不能以我能想到的所有方式来构建。 谁能帮帮我?

exchang_info.h

#ifndef EXCHANGE_INFO_H_
#define EXCHANGE_INFO_H_

#include <sys/time.h>
#include <fstream>
#include <stdio.h>
#include "define.h"
#include "info_type.h"
#include "order_side.h"
// #include "wrapstruct.h"

struct ExchangeInfo 
  InfoType::Enum type;
  char contract[MAX_CONTRACT_LENGTH];
  char order_ref[MAX_ORDERREF_SIZE];
  int trade_size;
  double trade_price;
  char reason[EXCHANGE_INFO_SIZE];
  OrderSide::Enum side;

  ExchangeInfo()
    : trade_size(0),
      trade_price(-1) 
  

  void Show(std::ofstream &stream) const 
    stream.write((char*)this, sizeof(*this));
  

  void ShowCsv(FILE* stream) const 
    /*  
    char time_s[32];
    snprintf(time_s, sizeof(time_s), "%ld.%ld", time.tv_sec, time.tv_usec);
    double time_sec = atof(time_s);
    */
    fprintf(stream, "%s,%s,%s,%d,%lf,%s,%s\n", InfoType::ToString(type),contract,order_ref,trade_size,trade_price,reason,OrderSide::ToString(side));
  

  void Show(FILE* stream) const 
    timeval time;
    gettimeofday(&time, NULL);
    fprintf(stream, "%ld %06ld exchangeinfo %s |",
            time.tv_sec, time.tv_usec, order_ref);

    fprintf(stream, " %lf@%d %s %s %s\n", trade_price, trade_size, 
    InfoType::ToString(type), contract, OrderSide::ToString(side));
  
;

#endif  //  EXCHANGE_INFO_H_

wrapstruct.h

#ifndef WRAPSTRUCT_H_
#define WRAPSTRUCT_H_

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

BOOST_PYTHON_MODULE(exchangeinfo) 
  class_<ExchangeInfo>("ExchangeInfo", init<>())
    .def_readwrite("type", &ExchangeInfo::type)
    .def_readwrite("contract", &ExchangeInfo::contract)
    .def_readwrite("order_ref", &ExchangeInfo::order_ref)
    .def_readwrite("trade_size", &ExchangeInfo::trade_size)
    .def_readwrite("trade_price", &ExchangeInfo::trade_price)
    .def_readwrite("reason", &ExchangeInfo::reason)
    .def_readwrite("side", &ExchangeInfo::side);
    //.def("Show", &ExchangeInfo::ShowCsv);
  enum_<InfoType::Enum>("InfoType")
    .value("Uninited", InfoType::Uninited)
    .value("Acc", InfoType::Acc)
    .value("Rej", InfoType::Rej)
    .value("Cancelled", InfoType::Cancelled)
    .value("CancelRej", InfoType::CancelRej)
    .value("Filled", InfoType::Filled)
    .value("Pfilled", InfoType::Pfilled)
    .value("Position", InfoType::Position)
    .value("Unknown", InfoType::Unknown);
  enum_<OrderSide::Enum>("OrderSide")
    .value("Buy", OrderSide::Buy)
    .value("Sell", OrderSide::Sell);
;

#endif //  WRAPSTRUCT_H_

编译命令:

g++ -std=c++11 -FPIC -shared wrapstruct.h -o exchangeinfo.so

可以编译出.so文件,但是不能被Python导入, 当我尝试导入exchangeinfo 时,错误如下:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /root/lib-hft/include/exchangeinfo.so: invalid ELF header

这些天真的很困扰我,有人可以帮助我吗? 你有更好的工具可以用来包装我的 c++ 代码以供 python 调用吗? 谢谢

【问题讨论】:

试试????python invalid elf header。 (我发现的另一个常见错误是下载错误操作系统的软件包,但在您的情况下这不太可能。) 可能不相关,但名为include 的目录可能不是拥有共享库的最佳位置。 @Scheff 我认为我对两者都使用了 x64,而其他的则很好运行。还是谢谢你的建议 通过查看命中列表(在我上面的链接中),我还看到了其他可能的错误。可能值得一看... @n.m.谢谢。 【参考方案1】:
g++ -std=c++11 -FPIC -shared wrapstruct.h -o exchangeinfo.so
                             ^^^^^^^^^^^^

没有。

您不能将头文件编译成目标代码。当您尝试时,gcc 会创建一个预编译头,而不是任何类型的目标文件。

% file exchangeinfo.so
exchangeinfo.so: GCC precompiled header (version 014) for C++

其他编译器可能会或可能不会做任何有用的事情。

要么将你的文件重命名为wrapstruct.cpp,要么创建一个新的文件,用一行这样命名

#include "wrapstruct.h"

并编译它。第一种方式更受欢迎; BOOST_PYTHON_MODULE宏定义了一个变量,这样的定义最好不要放在头文件中。


事实上,你可以强制 gcc 将具有任何扩展名的文件视为任何类型的文件;您可以添加 -x c++ 标志,gcc 会将其编译为 C++ 文件,而不管扩展名如何,但非常不建议这样做。

【讨论】:

如果我的回答正确,g++ 创建了一个预编译头文件命名 exchangeinfo.so。然而,预编译的标头是编码的——它当然没有 ELF 标头(也不能用作共享对象),并且会明显地解释暴露的导入错误。 (哇。)

以上是关于为啥我的由 boost.python 和 c++ 头文件编译的 .so 文件失败了?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的由代码创建的 UITextField 不能在我的 tableview Cell 中工作?

如何在 boost::python 扩展模块中正确组合 C++ 和 Python 代码?

实用观点:为啥要在 C++ 中使用 Python?

使用 boost::python 将回调从 python 传递到 c++

Boost.Python 与多处理兼容吗?

boost::python 和回调驱动的执行