从 Python 调用 API 时dynamic_cast失败C++
dynamic_cast failure while calling C++ API from Python
我正在尝试从python调用C++ API。以下是伪形式的代码。
class Engine { // Singleton Class which does a heavy duty work
public:
static Engine* getEngine();
bool init();
private:
static Engine* m_instance;
Engine();
};
// Following the code to wrap the call to engine to call from python
// Its only a simplified form
//engine_module.c
#include <Engine.h>
PyObject* initengine() {
Engine* e = Engine::getInstance();
e->init();
// return the Py_BuildValue ...
}
PyObject* initengine_module() {
//... init the module
}
// Python code
import engine_module
status = engine_module.init()
问题:引擎类处于 libengine.so 状态,当它启动时,它会失败,因为内部dynamic_cast失败。引擎依次使用 dlopen(( 加载其他库。我在链接时搜索了网络以添加 RTDL_GLOBAL 和 -E 选项,但仍未解决。我应该在编译 python 本身时添加 -E 选项吗?引擎类在C++代码中使用时运行良好,而在 python 中使用时不起作用的原因是什么?
编辑 1:澄清 Cat++ 中的问题:libengine.so 还有许多其他类,在 Engine::init(( 内部使用 dynamic_cast<>。dynamic_cast中涉及的类根本不会暴露给 python。只有 Engine::init(( 被公开。
编辑 2:平台是Red Hat Linux,编译器是Intel
问题是如何以及何时加载动态库。 代码你在 engine_module.c 中显示引用Engine
,所以库与 Engine
将在任何初始化之前自动加载执行 engine_module.c
中的代码。 同样,使用 Engine
将在加载包含Engine
的库之前加载。 都其中将使用 Python 用于加载其的标志加载接口模块。 (RTDL_LOCAL
是我的猜测。 您调用的任何dlopen
稍后会发现模块已经加载,并忽略请求 - 包括忽略您可能拥有的任何dlopen
选项通过。
我们解决这个问题的方法是创建一个特殊的加载器模块,它不包含对任何其他模块的直接引用。 蟒加载此模块,该模块实现initxxx
函数。 这 initxxx
函数显式加载所需的所有其他模块,在依赖关系确定的顺序。(如果 A 使用 B,B 将在 A 之前加载。当然是有RTDL_GLOBAL
。 在您的情况下,这将是Engine
使用的库,然后Engine
。 最后一个要加载的模块将是带有 Python 接口的那个;我们把蟒蛇静态对象的构造函数中的初始化代码,因此它将在加载对象时自动执行,但您也可以把它放在一个命名函数中,只要你得到这个的地址函数使用 dlsym
,而不是在任何声明中extern
时尚。 重要的是确保所有库首先由显式dlopen
加载,而不是由于之前加载的某些库中未定义的外部而隐式加载。
我最好的猜测是你试图将dynamic_cast
应用于一些非多态类,这就是它失败的地方。请记住,dynamic_cast
仅适用于至少具有一个虚拟方法(析构函数计数(的类。
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 如何理解C++标准N3337中的expr.const.cast子句8
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- C++Cast运算符过载
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 编译错误:C/ c++中cast void *失败