2012-05-02 14 views
5

タイトルごとに、私はCを使用してDLLを作成し、C++プロジェクトからリンクしようとしています。私はインターネット上のさまざまなチュートリアルを読んで、それに従っていましたが、何かが見当たらず、私は何が分からないのです。CでDLLを作成してC++プロジェクトからリンクする

はここで、私が何をしたかのステップバイステップです:

私はtestlibという名前の新しいWin32プロジェクトを作成し、その後、ウィザードから、私は「DLL」と「空のプロジェクト」を選択しました。

付加されたヘッダ:

//testlib.h 

#include <stdio.h> 

__declspec(dllexport) void hello(); 

追加されたソース。私はそれがCのソースにしたいので、私はそう

//testlib.c 

#include "testlib.h" 

void hello() { 
    printf("DLL hello() called\n"); 
} 

ビルドがsucceded、私はsimplly .Cで.cppファイルの名前を変更する必要があります読んで。

今、別のプロジェクトで役に立つDLLを使いたいと思います。

次に、新しいプロジェクト(testlibUse)。今回私は "Empty project"を選択しました。
ヘッダを追加する必要はありませんが、ちょうどその時のcppソース

//main.cpp 
#include <testlib.h> 

int main() { 
    hello(); 
} 

を作成しました:

  • を私はプロパティ - > VC++ directories->実行可能ファイルのディレクトリにされtestlib.dllフォルダへのパスを追加しました

  • フォルダには、[プロパティ - > VC++ディレクトリ - >インクルードディレクトリ]のtestlib.hのパスが追加されました。

  • 私が構築しようとしたが、私は、リンカのエラーを得たプロパティ - >リンカー - >入力 - >追加の依存関係にtestlib.lib(付属延長)に

をパスを追加しました:

LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" ([email protected]@YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals

testlibに戻った場合、testlib.cの名前をtestlib.cppに変更し、dllを再構築すると、testlibUseをビルドすることができますが、実行時に「dll not found」エラーが発生します。

"リリース"(必要に応じてパスを変更)で両方のプロジェクトの設定を変更しようとしましたが、何も変更されませんでした。

長いポストに申し訳ありませんが、私が行ったことを正確に書き留める必要があったと思います。

提案がありますか?

さらに、私がQtプロジェクトで自分のdllを使いたい場合に変更する必要のある設定パラメータはありますか?

答えて

9

あなたはいくつかの問題があります。

  1. 時にDLLにコンパイルされますが、インポートされたエクスポートされた機能をマークしなければならないヘッダファイルライブラリユーザーによってコンパイルされているとき。
  2. 名前がDLLを実行可能ファイルのライブラリ検索パス上にないマングルされた
  3. を取得しないことを確実にするためにC++としてコンパイルされたときにヘッダファイルがextern "C"ブロック内の関数宣言をラップする必要があり、それが見つかりません実行時にあなたの実行可能ファイルと同じフォルダにDLLをコピーし、(3)を固定するために

    #ifdef __cplusplus 
    extern "C" { 
    #endif 
    
    // Assume this symbol is only defined by your DLL project, so we can either 
    // export or import the symbols as appropriate 
    #if COMPILING_MY_TEST_DLL 
    #define TESTLIB_EXPORT __declspec(dllexport) 
    #else 
    #define TESTLIB_EXPORT __declspec(dllimport) 
    #endif 
    
    TESTLIB_EXPORT void hello(); 
    // ... more function declarations, marked with TESTLIB_EXPORT 
    
    #ifdef __cplusplus 
    } 
    #endif 
    

    :(1)を固定し、(2)、このようなあなたのヘッダを書き換えること

。設定している "実行可能ディレクトリ"の設定はDLL検索には影響しません - DLLの検索方法の詳細については、MSDNを参照してください。最適な解決策は、実行可能ファイルが存在するディレクトリにDLLをコピーすることです。これを手動で行うこともできますし、ビルド後のステップをプロジェクトに追加することもできます。

1

コンパイラがmangleではないことをcppビルドで確認する必要があるように見えます。 testlibの定義にextern "C"を追加できるはずです。H:

#ifdef __cplusplus 
extern "C" 
#endif 
__declspec(dllexport) void hello(); 
+0

ビルド成功したが、私は、実行時に「見つからないDLL」エラーが出ますが...プロパティ - > VC++ directories->実行可能ファイルのディレクトリにDLLへのパスを追加するのに十分ではなかったですか? – Saphrosit

+0

@Saphrosit:いいえ、私の知る限り、アプリの実行には影響しません。そのプロパティページの説明を読んでください。プロジェクトを構築している間にバイナリの発見に影響を与えます。実行時にDLLが検出される必要があります(PATH環境変数など)。 –

2

あなたはextern "C"はインクルードが含まれている必要があります

+0

ビルドは成功しましたが、実行時に "dll not found"エラーが発生しました...プロパティ - > VC++ディレクトリ - >実行可能ディレクトリのdllへのパスを追加するには十分ではありませんでしたか? – Saphrosit

1

これは、C++でインクルードできるCヘッダーファイルのメソッドです。 DLLプリプロセッサの設定でのみ、TESTLIB_EXPORTSを設定してください。 DLLを使用するこのヘッダーを含むプロジェクトでは、ヘッダーは関数をエクスポートではなくインポートとして宣言します。

__cplusplus guardは、C++の名前の装飾の代わりにCの名前の装飾を使用して関数をインポートするようにコンパイラに指示します。

#include <stdio.h> 

#ifdef TESTLIB_EXPORTS 
#define TESTLIB_API __declspec(dllexport) 
#else 
#define TESTLIB_API __declspec(dllimport) 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

TESTLIB_API void hello(); 
/* other prototypes here */ 

#ifdef __cplusplus 
} 
#endif 
関連する問題