2012-01-27 20 views
6

がマイライブラリLib.cファイルです:私はLib.dllLib.dllに対するLib.cMain.exeのリンクから来てLib.dll、およびMain.exeを、作成したいコマンドラインでWin32 DLLを作成してリンクするための正確な手順は何ですか?ここで

int helloworld(); 


int main(int argc, char** argv){ 
    helloworld(); 
} 

#include <stdio.h> 

int helloworld(){ 
    printf("Hello World DLL"); 
} 

ここに私のexe Main.cファイルです。

これを達成するための具体的な手順は何ですか?

+1

DLLを作成する場合は、dllmainが必要です –

+3

@MikeKwan:DllMainは[オプション]です(http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs)。 .85%29.aspx) – tinman

+0

この件については、多くのチュートリアルがありますが、なぜ私にGoogleにあなたにお尋ねするのかわからないのです。 – karlphillip

答えて

16

thisを参照してくださいDLLを構築する方法に関する質問。

あなたのライブラリコードはシンボルをエクスポートしません。実行可能ファイルはライブラリからシンボルをインポートしません。それを行うための2つの典型的なパターンを以下に示しますが、最初にそれを読みたいかもしれません。

最初の方法では、__declspec()を使用して、DLLからエクスポートされ、他の実行可能ファイルによってインポートされた関数(またはその他の項目)をコードで宣言します。あなたは、エクスポートされたアイテムを宣言し、シンボルが輸出または輸入されているかどうかを制御するために使用するプリプロセッサフ​​ラグを持っているヘッダファイルを使用します。

mylib.h:

#ifndef MYLIB_H 
#define MYLIB_H 

#if defined(BUILDING_MYLIB) 
#define MYLIB_API __declspec(dllexport) __stdcall 
#else 
#define MYLIB_API __declspec(dllimport) __stdcall 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

int MYLIB_API helloworld(void); 

#ifdef __cplusplus 
} 
#endif 

#endif 

を、私はまた、具体的に呼び出し規約を設定しています__stdcallはほとんどのDLL関数と同じです(windows.hをインクルードしていれば__stdcallの代わりにWINAPIを使用していた可能性があります)。extern "C"として関数を宣言しているので、C++としてコンパイルされたときに名前が変更されません。これはすべてC言語のような問題ではありませんが、CソースからDLLをビルドしてC++実行可能ファイルからDLLを使用しようとすると、インポートされた名前は正しくありません。

コードは次のようになります。

mylib.c

#include "mylib.h" 
#include <stdio.h> 

int MYLIB_API helloworld(void) 
{ 
    printf("Hello World DLL"); 
    return 42; 
} 

あなたは、次のコマンドラインを使用してDLLをビルドすると思います。同様に、それは別の実行ファイルからあなたのDLLを使用するために必要なインポートライブラリ(.libファイル)を作成しますDLLの作成(だけでなく、エクスポートファイルを、それが唯一のcertain circumstancesに必要とされる)のように:

cl /DBUILDING_MYLIB mylib.c /LD 

/DBUILDING_MYLIB引数は、DLL内の関数がエクスポート(定義されている場合)またはインポート(定義されていない場合)であるかどうかを制御するプリプロセッサシンボルを定義します。したがって、DLLをビルドするときに定義しますが、アプリケーションをビルドするときは定義しません。

パラメータ/LDは、clにDLLを生成するよう指示します。

第2の方法は、コメントで述べたようにmodule definition filesを使用することです。すでに持っているコードを使用できますが、モジュール定義ファイルも作成する必要があります。で、それはこのようになります最も簡単です:あなたは、次のコマンドラインを必要とするDLLを構築するためにこの場合

LIBRARY mylib 
EXPORTS 
    helloworld 

cl /LD mylib.c /link /DEF:mylib.def 

それはであなたのライブラリヘッダーを使用するようにあなたは、あなたのアプリケーションをコーディングすることができDLL関数の輸入版:

main.cの

/* No need to include this if you went the module definition 
* route, but you will need to add the function prototype. 
*/ 
#include "mylib.h" 

int main(void) 
{ 
    helloworld(); 
    return (0); 
} 

次に、次のコマンドラインでコンパイルできます(DLL作成のインポートライブラリがmain.cと同じディレクトリにあると仮定します)。彼らが表示されるようちょうどファイル名として、それはへの追加の入力として使用されるように/link引数は、リンカのコマンドラインに渡された後、渡さ

cl main.c /link mylib.lib 

引数:この手順は、declspecまたはモジュール定義ファイルを使用したかどうかと同じです実行可能ファイルにリンクします。この場合、DLLをビルドしたときに生成されるインポートライブラリを指定します。

私がここに示したコマンドラインは、必要最小限のものですが、DLLを作成してアプリケーションをリンクすることができます。

上記のすべてで呼び出し規約が正しいと仮定しましたが、私はいつでも間違っているかどうかを試していません。

+0

.dllを作成すると同時に.libも作成されるという事実をより明確にする必要があります。 –

+0

この回答は良いです。 '__declspec'拡張を使用したくない場合は、[モジュール定義ファイル] [http://msdn.microsoft.com/en-us/library/28d6s79h(v = vs.100).aspx]を作成することができます。エクスポートされたインターフェイスを指定します。それは、あなたが何をどのように(そしてどのように)外部に公開するかをより詳細に制御することができます。 –

+1

エクスポートされたシンボルには 'extern" C "'を使用し、 '__stdcall'(または' WINAPI'マクロ)を使用することもできます。 –

関連する問題