1

我正在尝试修改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 调用?

4

1 回答 1

1

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

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

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

编辑:看起来也有在 Unix 中使用 C++ 虚拟基类的方法。

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

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

#define bind udt_calls->bind
于 2012-01-27T20:33:07.420 回答