【问题标题】:Choosing library to link at runtime在运行时选择要链接的库
【发布时间】:2012-01-27 19:52:54
【问题描述】:

我正在尝试修改 iperf 以支持另一种协议 (UDT)。 UDT API 的编写方式反映了标准 BSD 调用:

  socket(...);
  bind(...);
  listen(...);

然后我需要做的是有条件地与 UDT 库链接,以便 iperf 中的这些调用将使用 UDT 代码而不是 TCP 堆栈的套接字接口。这可以做到吗?我总是可以只加载库并使用 UDT:: 命名空间有另一个条件路径,但会有 1)与 TCP 路径有很多重复,2)有很多可能不需要的更改。如果我不清楚,请告诉我,任何关于如何实现这种动态链接的建议都非常感谢。

编辑:

使用下面提到的 dlopen() 系列,我可以有以下程序流程:

解析命令行参数 -> 如果请求 UDT,则加载库 libudt -> 获取和存储所有 UDT BSD 函数(绑定、监听等)的句柄

此时,我的所有 UDT 函数都存储了函数指针。假设我将它们全部存储在一个名为 udt_calls 的结构中。现在,我对现有代码有一个问题,它只是进行如下调用:

          bind(...)

而不是:

         udt_calls->bind(...)

有没有一种干净的方法可以使用我现在加载的 udt_calls 结构中的函数指针全局覆盖整个程序中的任何 BSD 调用?

【问题讨论】:

  • 你做过这个吗?是否有执行 UDT 的补丁或 iperf 版本?

标签: c++ tcp libraries udp-data-transfer


【解决方案1】:

是的,这可以做到。您需要使用动态库加载。在 Windows 中,这是使用 LoadLibrary 完成的。在 Linux 或 Unix 中,它是使用 dlopen 和朋友完成的。

您需要阅读文档并查看这些函数的示例。快速总结一下,您创建了一堆函数指针(通常在结构中完成,在 Windows 上,有一些技巧可以将它们加载到 C++ 虚函数类中)。然后你使用动态加载函数打开一个库,然后分配你的函数指针指向库中的函数。

然后,您使用函数指针(或 C++ 虚函数)进行函数调用。

编辑:It looks like there are ways to use C++ virtual base classes in Unix as well.

编辑:我相信大多数系统都会使操作系统库使用“弱”符号。这意味着您可以定义自己的同名全局符号并覆盖 OS 库版本。尝试在自己的程序中声明全局函数指针,以提供bindlisten 的全局版本。

另一种选择可能是在结构中声明指针,然后使用预处理器定义如下:

#define bind udt_calls->bind

【讨论】:

  • 谢谢!这似乎正是我正在寻找的。但是,如果您在上面看到我的编辑,我仍然对预先编写的代码有疑问。您能提出解决方案吗?
  • @agent0range:尝试在你自己的程序中声明一个全局函数指针来覆盖bind的操作系统库版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多