1

GnuTLSを使用するプロジェクトをVisualStudio2012でビルドしようとしています。Webサイトから最新の公式Windowsビルドをダウンロードし、lib /def:libgnutls-28.defVisualStudioコマンドプロンプトからbinディレクトリで実行してリンクライブラリを作成しました。

を追加するtypedef long ssize_tと、コードは正常にコンパイルされますが、リンクは次のエラーで失敗します。

source_file.obj : error LNK2001: unresolved external symbol _gnutls_free
C:\Path\to\executable.exe : fatal error LNK1120: 1 unresolved externals

gnutls_freeライブラリによって割り当てられて返されたメモリを解放するように呼び出しています。の呼び出しを削除するとgnutls_free、プロジェクトは正常にリンクされます。これがライブラリによってエクスポートされた単なるグローバル変数(関数ポインタを含む)であることを考えると、gnutls_freeそれにアクセスすると別のシンボルへの未解決の参照が発生する理由がわかりません。私はそれが何にも編集されてgnutls_freeいないことを確認しました。#define

gnutls_free_function test = gnutls_free;テストとして、リンクエラーが発生することを試してみました。GnuTLSソースコードで実行grep -w -r _gnutls_free .しても何も返されないので、途方に暮れています。

これを機能させるためのアイデアをいただければ幸いです。

編集:

in__declspec(dllimport)の宣言に追加すると、リンクが成功します。ヘッダーファイルのカスタムバージョンを維持せずにこれを達成する方法はありますか?gnutls_freegnutls.h

4

1 に答える 1

1

関数に対して行われるのと同じ方法で、リンカまたはインポート ライブラリがデータ項目への IAT ポインタを自動的に逆参照するようにする方法はないようです (関数をインポートするモジュールに静的にリンクされた小さなトランポリン関数を介して)。 . この__declspec(dllimport)属性は、この逆参照を実行する必要があることをコンパイラに伝え、IAT ポインターの逆参照を暗黙的に実行するコードを挿入できるようにします。これにより、エクスポートされたデータにアクセスできるようになり、関数の場合、コンパイラはトランポリン関数を呼び出すのではなく、IAT ポインターを介した間接呼び出しを介してインポートされた関数を呼び出すことができます。

dllimport関数呼び出しで何が行われるかについての適切な説明については、Raymond Chen のいくつかの記事を参照してください(残念ながら、彼はデータのインポートについては説明していません)。

MS リンカまたはインポート ライブラリには、コンパイラがインポートされたデータを「素朴な」方法で取得するのに役立つメカニズムがありません。コンパイラは__delcspec(dllimport)、IAT による追加の逆参照が必要であるというヒントを必要とします。__declspec(dllimport)とにかく、このすべてのポイントは、属性を使用する以外にデータをインポートする方法がないように見えるということです。

ディストリビューションの変更を避けたい場合gnutls(私には理解できます)、不完全な回避策が 1 つあります。

の単純なラッパーだけを含む小さなオブジェクト ファイルを作成できますgnutls_free()。にgnutls_free()は実際の依存関係のないインターフェースがあるため、以下を含める代わりに、必要な宣言を「ハードコード」することができますgnutls.h

typedef void (*gnutls_free_function) (void *);
__declspec(dllimport) extern gnutls_free_function gnutls_free;

void xgnutls_free(void* p)
{
    gnutls_free(p);
}

xgnutls_free()の代わりにコードを呼び出しますgnutls_free()

優れた解決策ではありません - コードでラッパーを呼び出す必要があります (したがって、に依存する可能性のあるサード パーティのコードを組み込む場合は特に優れていませんgnutls_free()) が、それで十分な場合があります。

于 2013-01-30T11:00:52.233 に答える