1

別のプロトコル (UDT) をサポートするようにiperfを変更しようとしています。UDT API は、標準の BSD 呼び出しを反映するように記述されています。

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

次に、UDT ライブラリと条件付きでリンクして、iperf のこれらの呼び出しが TCP スタックへのソケット インターフェイスの代わりに UDT コードを使用するようにする必要があります。これはできますか?私はいつでもライブラリをロードし、UDT:: 名前空間を使用して別の条件付きパスを持つことができますが、1) TCP パスからの重複が多く、2) 変更が必要ない場所で多くの変更が行われる可能性があります。明確でない場合はお知らせください。この動的リンクを実現する方法についての提案をお待ちしております。

編集:

以下で説明する dlopen() ファミリを使用すると、次のプログラム フローを作成できます。

cmd line params を解析 -> UDT が要求された場合、ライブラリ libudt をロード -> すべての UDT BSD 関数 (bind、listen など) のハンドルを取得して保存

この時点で、すべての UDT 関数と共に関数ポインターが格納されています。それらすべてを udt_calls という構造体に格納しているとしましょう。今、次のような呼び出しを行う既存のコードに問題があります。

          bind(...)

それよりも:

         udt_calls->bind(...)

udt_calls 構造体にロードされた関数ポインターを使用して、プログラム全体で BSD 呼び出しをグローバルにオーバーライドできるクリーンな方法はありますか?

4

1 に答える 1

1

はい、これは可能です。ダイナミックライブラリの読み込みを使用する必要があります。Windowsでは、これはを使用して行われLoadLibraryます。LinuxまたはUnixでは、andfriendsを使用して実行されdlopenます。

ドキュメントを読み、それらの関数のサンプルを確認することをお勧めします。簡単な要約は、一連の関数ポインターを作成することです(多くの場合、構造体で行われ、Windowsでは、それらをC ++仮想関数クラスにロードするためのいくつかのトリックがあります)。次に、動的ロード関数を使用してライブラリを開き、ライブラリ内の関数を指すように関数ポインターを割り当てます。

次に、関数ポインター(またはC ++仮想関数)を使用して関数呼び出しを行います。

編集:UnixでもC++仮想基本クラスを使用する方法があるようです。

編集:ほとんどのシステムでは、オペレーティングシステムライブラリに「弱い」記号を使用させると思います。つまり、同じ名前の独自のグローバルシンボルを定義し、OSライブラリのバージョンを上書きできます。bindとのグローバルバージョンを提供するには、独自のプログラムでグローバル関数ポインタを宣言してみてくださいlisten

別のオプションは、構造体でポインターを宣言してから、次のようなプリプロセッサー定義を使用することです。

#define bind udt_calls->bind
于 2012-01-27T20:33:07.420 に答える