dlsym()和dlopen()在C ++中的替代方法 [英] Alternatives to dlsym() and dlopen() in C++

查看:3397
本文介绍了dlsym()和dlopen()在C ++中的替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序的一部分使用共享库。这些库在编译时链接。


在运行时,加载器期望共享对象在 LD_LIBRARY_PATH 中,如果没有找到,整个应用程序崩溃,出现错误无法加载共享库。注意,不能保证客户端将有库,在这种情况下,我想让应用程序留下合适的错误消息,独立部分应该正常工作。

I have an application a part of which uses shared libraries. These libraries are linked at compile time.
At Runtime the loader expects the shared object to be in the LD_LIBRARY_PATH , if not found the entire application crashes with error "unable to load shared libraries".Note that there is no guarantee that client would be having the library, in that case I want the application to leave a suitable error message also the independent part should work correctly.

为此,我使用 dlsym() dlopen()共享库。问题是如果我有很多的API,我必须使用 dlsym()和ptrs访问它们在我的情况下,导致内存损坏

For this purpose I am using dlsym() and dlopen() to use the API in the shared library. The problem with this is if I have a lot of functions in the API, i have to access them Individually using dlsym() and ptrs which in my case are leading to memory corruption and code crashes.

有任何替代方案吗?

推荐答案

你的问题的常见解决方案是声明一个函数指针表,做一个单一的dlsym()来找到它,然后通过指向该表的指针调用所有其他函数。示例(未测试):

The common solution to your problem is to declare a table of function pointers, to do a single dlsym() to find it, and then call all the other functions through a pointer to that table. Example (untested):

// libfoo.h
struct APIs {
   void  (*api1)(void);
   void *(*api2)(int);
   long  (*api3)(int, void *);
};

// libfoo.cc
void fn1(void) { ... }
void *fn2(int) { ... }
long fn3(int, void *) { ... }

APIs api_table = { fn1, fn2, fn3 };


// client.cc
#include "libfoo.h"
...
  void *foo_handle = dlopen("libfoo.so", RTLD_LAZY);
  if (!foo_handle) {
     return false;            // library not present
  }
  APIs *table = dlsym(foo_handle, "api_table");
  table->api1();              // calls fn1
  void *p = table->api2(42);  // calls fn2
  long x = table->api3(1, p); // calls fn3

使用dlsym和指针单独访问您的API函数本身不会导致内存损坏和崩溃。很可能你只是有错误。

P.S. Accessing your API functions individually using dlsym and pointers does not in itself lead to memory corruption and crashes. Most likely you just have bugs.

编辑:

你可以使用这个完全相同的技术与第三方库。创建 libdrmaa_wrapper.so 并将 api_table 添加到其中。将包装器直接链接到 libdrmaa.so


You can use this exact same technique with a 3rd-party library. Create a libdrmaa_wrapper.so and put the api_table into it. Link the wrapper directly against libdrmaa.so.

在主可执行文件中, dlopen libdrmaa_wrapper.so,RTLD_NOW)。如果(而且只有) libdrmaa.so 在运行时出现,并且提供您使用的所有API函数,此 dlopen api_table 中。如果它成功,单个 dlsym 调用将允许您访问整个API。

In the main executable, dlopen("libdrmaa_wrapper.so", RTLD_NOW). This dlopen will succeed if (and only if) libdrmaa.so is present at runtime and provides all API functions you used in the api_table. If it does succeed, a single dlsym call will give you access to the entire API.

这篇关于dlsym()和dlopen()在C ++中的替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆