我目前正在开发一个程序,该程序应该对自制的数据结构进行计算。
我想以一种易于添加支持的计算的方式构建它(比如,作为符合预定结构的源文件)。
问题在于我不想提前加载所有计算,因为可能会有很多计算。 我发现支持动态加载功能的唯一机制是dlopen,它需要.so文件,所以在这个上下文中,使用dlopen意味着为每组计算编译一个单独的so文件。
虽然我没有看到这个设计存在任何固有的问题,但我的蜘蛛感觉告诉我,我应该用全知的网络验证它并不是完全愚蠢的。如果有任何其他建议的方法,我会很高兴听到。
答案 0 :(得分:1)
使用dlopen()
是在POSIX兼容操作系统上的应用程序中动态加载可执行代码的最广泛使用的方法。它允许使用模块化架构,其中可选或很少使用的代码仅按需加载,这听起来非常像您需要的。
我肯定会使用这种方法 - 如果经过一段时间后你发现共享对象编译步骤成为障碍,你可以构建额外的动态加载模块来支持例如一种解释的语言,如Lua或Python。这样您就可以保留现有代码库而不会丢失可扩展性。
答案 1 :(得分:1)
似乎是一种很好的方法。
这样做的一个好方法是在C ++中声明一个抽象(纯)类,比如说Calculator
,它包含执行计算所需的所有方法和访问器。然后,让您的单独动态库或.so文件实现一个全局函数Calculator * create_calculator()
,它创建一个派生自Calculator
的类的实例。最后,您必须设计一个注册机制,以便您的主程序可以根据某种标识符(如字符串,枚举或uuid)确定要加载的动态库的名称。这通常可以作为易于编辑的配置文件使用。
void *handle;
int (*create_calculator)();
/* open the needed object file */
char *libName = get_lib_name_from_config(identifier);
handle = dlopen(libName, RTLD_LOCAL | RTLD_LAZY);
/* find the address of create_calculator function */
create_calculator = (*(Calculator*)()) dlsym(handle, "create_calculator");
Calculator * calc = create_calculator();
通过允许create_calculator
方法名称变化,可以使此方案更灵活(也更复杂),但代价是必须从配置文件中获取该方案。
答案 2 :(得分:0)
使用dlopen()打开共享库肯定是我想到的第一件事;这是一个很好的计划。