当前位置: 首页 > 面试题库 >

如何从共享库调用函数?

顾乐心
2023-03-14
问题内容

从共享库/ dll调用函数的最简单,最安全的方法是什么?我对在Linux上执行此操作最感兴趣,但是如果有一种与平台无关的方法会更好。

有人可以提供示例代码来显示如何在用户将自己的版本编译foo到共享库的情况下执行以下工作吗?

// function prototype, implementation loaded at runtime:
std::string foo(const std::string);

int main(int argc, char** argv) {
  LoadLibrary(argv[1]); // loads library implementing foo
  std::cout << "Result: " << foo("test");
  return 0;
}

顺便说一句,我知道如何编译共享库(foo.so),我只需要知道一种在运行时加载它的简单方法。


问题答案:

注意: 您正在库调用周围传递C 对象(在这种情况下为STL字符串)。有 **没有标准的C
ABI
在这个水平**,所以无论是尽量避免将C
++对象周围,或确保两个资料库和程序已建成具有相同的编译器(最好在同一台机器上相同的编译器,以避免任何微妙与配置相关的惊喜。)

不要忘记在库代码中 声明导出的方法extern "C"

上面已经说过了,这是 一些代码,实现您要实现的目标

typedef std::string (*foo_t)(const std::string);
foo_t foo = NULL;

...

# ifdef _WIN32
  HMODULE hDLL = ::LoadLibrary(szMyLib);
  if (!hDll) { /*error*/ }
  foo = (foo_t)::GetProcAddress(hDLL, "foo");
# else
  void *pLib = ::dlopen(szMyLib, RTLD_LAZY);
  if (!pLib) { /*error*/ }
  foo = (foo_t)::dlsym(pLib, "foo");
# endif
  if (!foo) { /*error*/ }

  ...

  foo("bar");

  ...

# ifdef _WIN32
  ::FreeLibrary(hDLL);
# else
  ::dlclose(pLib);
# endif

您可以 进一步抽象

#ifdef _WIN32
#include <windows.h>
typedef HANDLE my_lib_t;
#else
#include <dlfcn.h>
typedef void* my_lib_t;
#endif

my_lib_t MyLoadLib(const char* szMyLib) {
# ifdef _WIN32
  return ::LoadLibraryA(szMyLib);
# else //_WIN32
  return ::dlopen(szMyLib, RTLD_LAZY);
# endif //_WIN32
}

void MyUnloadLib(my_lib_t hMyLib) {
# ifdef _WIN32
  return ::FreeLibrary(hMyLib);
# else //_WIN32
  return ::dlclose(hMyLib);
# endif //_WIN32
}

void* MyLoadProc(my_lib_t hMyLib, const char* szMyProc) {
# ifdef _WIN32
  return ::GetProcAddress(hMyLib, szMyProc);
# else //_WIN32
  return ::dlsym(hMyLib, szMyProc);
# endif //_WIN32
}

typedef std::string (*foo_t)(const std::string);
typedef int (*bar_t)(int);
my_lib_t hMyLib = NULL;
foo_t foo = NULL;
bar_t bar = NULL;

...

  if (!(hMyLib = ::MyLoadLib(szMyLib)) { /*error*/ }
  if (!(foo = (foo_t)::MyLoadProc(hMyLib, "foo")) { /*error*/ }
  if (!(bar = (bar_t)::MyLoadProc(hMyLib, "bar")) { /*error*/ }

  ...

  foo("bar");
  bar(7);

  ...

  ::MyUnloadLib(hMyLib);


 类似资料:
  • 问题内容: 我有一个.so文件,我想在我的Go代码中调用其功能。 我该怎么做呢?我已经阅读了cgo和syscall软件包。它们接近我想要的位置,但是我看不到可以在.so文件中调用函数的任何地方。 我想确切地实现ctypes包在Python中的功能。 有人可以帮忙吗? 问题答案: 如果要使用在编译时静态已知的共享库,则可以简单地使用cgo。阅读有关如何准确执行此操作的文档,但是通常您会指定一些链接器

  • 我正在尝试开发共享库,目录结构如下 src/com/mycomapny 我的测试。棒极了 测试。棒极了 我的Jenkinsfile调用test.groovy中唯一可用的方法,需要输入。它导入MyTest并创建对象,调用构造函数,然后是执行MyTest.groovy文件中可用功能的实际方法 在这里,构造函数类从未从全局vars/test调用过。棒极了 我尝试从groovy调用类和方法,它工作正常,但

  • 问题内容: 谁能告诉我如何对共享库进行运行时调试? 我需要在运行时调试共享库中的一个函数,但另一个程序会调用它。如何使用共享库执行类似dbx的操作? 我在AIX上使用dbx。我想做的是gdb比dbx好吗? 问题答案: 您只需要使用可执行文件调用gdb(无论是您的文件还是第三方文件都没有关系)。这是一个示例,其中我调试 ls 命令并在(共享) c库中 设置断点。此示例使用了gdb 6.8,它支持延迟

  • 问题内容: 我使用Windows Host上的RVDS编译器使用目标代码文件(C源代码)创建了一个共享库()。 我将此共享库与一个应用程序链接(用于Linux主机上的ARM目标)并获得一个可执行文件,该可执行文件在运行时会产生分段错误。(我知道我必须调试它!) 如果不创建共享库,而是创建具有相同源文件的静态库,然后与该应用程序链接,然后执行该应用程序,则可以正常运行。 所以我的问题是: 我是否需要

  • 问题内容: 使用GCC,如何在创建共享库后从共享库中删除符号?如果我在C中使用三个文件来处理符号,例如: 和 和 然后我像这样编译并运行: 我怎样才能让这个不再具有象征我已经创建后?我希望使用中定义而不是 从中 删除符号。之后从删除,再运行应该产生的打印输出: 在这个玩具示例中,我知道用and 编译时可以简单地对库名称进行重新排序,但是实际上如何从中删除符号呢?我想象在从中删除后,nm输出的这个g

  • 我试图从一个位于vars下的新脚本中获取信息,该脚本是从共享库Jenkins类调用的,但出错了。 > 需要-全局配置文件。 目标-能够在共享库中获取全局值,而无需从Jenkins文件发送参数。 文件结构 变量/全局变量。棒极了 shared_library类 詹金斯档案 因此,我可以看到管道中第一次打印的值,但对于第二次打印,我得到: 类:src没有这样的属性:globals。组织。詹金斯。共享图