2016-12-28 3 views
1

Visual Studioでは、関数をdllから序数でエクスポートしたいと考えています。ソースでは私がする関数を定義:.defファイルで関数をdllから序数でエクスポートするだけでは関数名は表示されません

int my_function() { return 101; }  // without declspec(dllexport) 

#pragma comment(lib, "MyDll.lib") 

declspec(dllimport) int my_function(); 

int main(int argc, char* argv[]) 
{ 
    int a = my_function(); 

    return 0; 
} 

コードをコンパイルし、罰金のリンク:メインプログラムで

LIBRARY MyDll 
    EXPORTS 
     my_function @ 1 NONAME  // NONAME, export directory will not contain function name 

私はこのようにそれを使用します。 NONAME属性は、序数でのみエクスポート機能に文書化されています。

MyDllのエクスポートディレクトリにはNumberOfNamesがゼロに設定されているため、dll自体には名前情報が含まれていません。 exeファイルは順序値で関数をインポートするので、exeには名前情報も含まれません。

私はさまざまな構成(デバッグ、リリース)を試みましたが、まだプログラムのリンクは正常です。たぶん、libファイルに関数名と序数の間にある種のマッピングが含まれているのでしょうか?私は、LIBファイルは関数サンクが含まれていることを読んで、私たちは、この内部のlibファイルのようなものを持つことができます。

my_function @ 1: 
    jmp IAT[0] 
my_another_function @ 2: 
    jmp IAT[1] 

とIn-ファイルexeファイルのインポートテーブル:

OriginalFirstThunk   FirstThunk 
0x80000001 (@ 1)   0x80000001 (@ 1) // ordinal 1 will go through IAT[0] 
0x80000002 (@ 2)   0x80000002 (@ 2) // ordinal 2 will go through IAT[1] 

そして、メモリ内のexeファイルのインポートテーブル:

OriginalFirstThunk   FirstThunk 
0x80000001 (@ 1)    IAT[0] 
0x80000002 (@ 2)    IAT[1] 

もしそうなら、我々は唯一のdllファイルを提供する必要があり、そしてそれは、ユーザーがLoadLibraryでDLLをロードし、GetProcessAddressを使用する必要がありますを意味し、関数名を隠すために?私はここで何が欠けているのですか? MSDNのExporting Functions from a DLL by Ordinal Rather Than by Nameから

+1

コードをコンパイルしてリンクすると、正確にはあなたの質問は何ですか? – selbie

+0

@selbie:なぜそれがうまくリンクしているのか知りたいのですが、すべきではありません。 – igntec

+0

"libファイルには関数のサンクが含まれています。" - これは当てはまりません。 – RbMm

答えて

0

あなたのDLLのファイルサイズを最適化したい場合は、それぞれのエクスポート機能にNONAME属性を使用します。 NONAME属性では、関数名ではなく、DLLのエクスポートテーブルに序数が格納されます。多くの機能をエクスポートする場合、これはかなりの節約になります。

つまり、NONAMEはインポートライブラリではなくDLLにのみ影響します。したがって、あなたが観察している動作は意図通りです。 documentation for EXPORTSから

オプションのキーワードPRIVATEはLINKによって生成されたインポートライブラリに含まれているからENTRYNAMEを防ぐことができます。

PRIVATEとNONAMEの両方を使用する場合は、必要な結果を得る必要があります。しかし、これは、少なくともその特定の機能が実現する限り、最初にインポートライブラリを提供するという目的を破るものです。インポートライブラリを介してアクセスできる一部の機能と、GetProcAddressを介してのみアクセスできる機能が必要な場合は、便利です。

エンドユーザーがリンクするために使用できる機能の別名を指定することをお勧めします。、

LIBRARY MyDll 
    EXPORTS 
     function1=my_function @ 1 NONAME 
     function2=my_other_function @ 2 NONAME 

これは「まだ秘密の名前「は、my_function」を隠しながら、エンドユーザーは、それらの名前を使用しての機能にリンクできるように、インポートライブラリに偽の名前を「関数1」と「機能2」を入れて、必要がありますインポートライブラリとDLLの両方で "my_other_function"を使用します。 (名前がなぜ最初に秘密になっている必要があるのか​​分かりませんが、YMMVです。)

免責事項:私はこれを試したことはありません。この回答はドキュメントのみに基づいています。

関連する問題