我在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 ++中的全局变量的初始化顺序无法控制。但也许还有另一种方法可以做得更好吗?
Hello.py
以防止用户简单地删除对LicenseManager的调用。但是后来安全性很差,因为Python很容易反编译。答案 0 :(得分:0)
回答我自己的问题。
实际上,Swig可以添加在库初始化期间调用的C ++代码。然后我只需要在Swig文件中添加以下代码:
%init%{
LicenseManager::get();
%}