库中的全局变量在使用时尚未初始化
Global variable from a library not yet initialized when used
上下文:
我用C++为Python创建了一个模块(我称之为Hello)。C++和Python之间的接口是由Swig制作的。它生成一个动态库_Hello.so
和一个Python文件Hello.py
。然后,当创建时,我只需要这样称呼它:
python
>>> import Hello
>>> Hello.say_hello()
Hello World !
>>>
我想用许可证保护这个模块,然后我希望在导入模块时加载许可证。
我的实现:
为了确保在导入模块时加载许可证,我创建了一个实例化全局变量的单例:
文件LicenseManager.hpp
:
class LicenseManager
{
private:
static LicenseManager licenseManager; // singleton instance
public:
static LicenseManager& get(); // get the singleton instance
public:
LicenseManager(); // load the license
~LicenseManager(); // release the license
private:
LicenseManager(const LicenseManager&); // forbidden (singleton)
LicenseManager& operator = (const LicenseManager&); // forbidden (singleton)
};
文件LicenseManager.cpp
:
LicenseManager LicenseManager::licenseManager; // singleton instance
LicenseManager& LicenseManager::get()
{
return LicenseManager::licenseManager;
}
LicenseManager::LicenseManager()
{
/*
* Here is the code to check the license
*/
if(lic_ok)
std::cout << "[INFO] License found. Enjoy this tool !" << std::endl;
else
{
std::cerr << "[ERROR] License not found..." << std::endl;
throw std::runtime_error("no available licenses");
}
}
LicenseManager::~LicenseManager()
{}
这非常有效!当我加载模块时,我获得:
python
>>> import Hello
[INFO] License found. Enjoy this tool !
>>> Hello.say_hello()
Hello World !
>>>
我的问题:
实际上,在我的构造函数中检查许可证的代码使用了库Crypto++。我有一个来自这个库的分段错误,但主函数中的相同代码工作得很好。然后我认为Crpyto++也使用全局变量,当调用LicenseManager
的构造函数时,这些变量还没有初始化。
我知道C++中全局变量的初始化顺序没有控制。但也许还有另一种方法可以做得更好?
错误的解决方案:
- 如果单例未初始化为全局变量,则模块在导入时不受保护。解决方案可以是在模块的每个功能中添加一个检查,并强制用户在使用前调用LicenseManager。这对我来说不是一个解决方案,因为我不能重写我的所有模块来强加它(实际上这个模块相当大)
- 在Swig配置文件中,我可以添加加载模块时调用的Python代码。然后,我必须编译
Hello.py
,以防止用户简单地删除对LicenseManager的调用。但它的安全性很差,因为Python很容易反编译
回答我自己的问题。
实际上,Swig可以添加在库初始化期间调用的C++代码。然后我只需要在Swig文件中添加以下代码:
%init%{
LicenseManager::get();
%}
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员