选择要在运行时链接的库

时间:2012-01-27 19:52:54

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

我正在尝试修改iperf以支持其他协议(UDT)。编写UDT API使其镜像标准BSD调用:

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

我需要做的是,有条件地链接到UDT库,以便iperf中的这些调用将使用UDT代码而不是TCP堆栈的套接字接口。可以这样做吗?我总是可以加载库并使用UDT ::命名空间创建另一个条件路径,但是会有1)从TCP路径中复制很多,2)需要进行大量更改。如果我不清楚,请告诉我,有关如何实现这种动态链接的任何建议都表示赞赏。

编辑:

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

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

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

          bind(...)

而不是:

         udt_calls->bind(...)

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

1 个答案:

答案 0 :(得分: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