2017-04-13 4 views
0

これはおそらく、私がC++/CLIの知識が不足しているために起こりますが、どこからでもこの質問を見つけることはできません。管理されたプロジェクトにネイティブクラスを追加する

私は、/ CLRでコンパイルされ、RefClass.cppという名前の(C++/cli)refクラスと、CppClass.cppというネイティブのC++クラスを持つManagedProjectというプロジェクトを持っています。

RefClassからCppClassのコンストラクタを呼び出すことができます。

しかし、別のプロジェクト "OtherProject"からCppClassを呼び出すことはできません。これは/ clrでもコンパイルされています。 OtherProjectにはOther.cppしかありません。 OtherProjectはManagedProjectへの参照を持っているので、RefClassを呼び出すことができますが、CppClassのコンストラクターを呼び出そうとすると、#include "CppClass.h"でもLNK2019とLNK2028エラーが発生します。

非/ clrネイティブクラスから呼び出すときに同じエラーが発生します。ここ


はコードサンプルである:

ManagedProject

RefClass.cpp:

// has a .h file with the constructor declaration & instance variable int test; 
#include "CppClass.cpp" 
RefClass:RefClass(int test){ 
    this->test = test; 
    CppClass inst(42); //This works 
} 

CppClass.cpp:

// has a .h file with the constructor declaration & instance variable int test2; 
CppClass:CppClass(int test2){ 
    this->test2 = test2; 
} 

OtherProject

Other.cpp:

#include "CppClass.cpp" 
int wmain(/*args*/){ 
    RefClass^ refinst = gcnew RefClass(64); //This works  
    CppClass inst(42); //This fails, I get LNK2019 & LNK2028 at Other.obj 
} 

実際のエラー出力: 注:ここSQLPrecheckReportはCppClassで、appzsqlmigrate.cppはOther.cppで、appzsqlmigrateはの名前ですその他のプロジェクト。

32> appzsqlmigrate.obj:エラーLNK2028:未解決のトークン(0A000B59) "公共:__cdecl SQLPrecheckReport :: SQLPrecheckReport(INT)" で参照 (?? 0SQLPrecheckReport @@ $$ FQEAA @ H @ Z)機能 "INT __cdecl wmain(int型、wchar_t型* * CONST)"(wmain @@ $$ HYAHHQEAPEA_W @ Z?)

32> appzsqlmigrate.obj:エラーLNK2028:未解決のトークン(0A000B5A) 「公共:__cdecl SQLPrecheckReport "int __cdecl wmain(int、wchar_t * * const)"(?wmain @@ $$ HYAHHQEAP)関数で参照されている:(?? 1SQLPrecheckReport @@ $$ FQEAA @ XZ) EA_Wする@ Z)

32> appzsqlmigrate.obj:エラーLNK2019:未解決の外部シンボル "パブリック:__cdecl SQLPrecheckReport :: SQLPrecheckReport(INT)" (?? 0SQLPrecheckReport @@ $$ FQEAA @ H @ Z)で参照機能 "INT __cdecl wmain(int型、wchar_t型* * CONST)"(wmain @@ $$ HYAHHQEAPEA_W @ Z?)

32> appzsqlmigrate.obj:エラーLNK2019:未解決の外部シンボル 「公共:__cdecl SQLPrecheckReport :: 〜SQLPrecheckReport(void) " (??1SQLPrecheckReport @@ $$ FQEAA @ XZ)関数で参照 "のint __cdecl wmain(int型、wchar_t型* * CONST)"(?wmain @@ $$ HYAHHQEAPEA_W @ Z)

+1

CLRはモジュールに対する優れたサポートを提供しますが、そのサポートをアンマネージドコードにも遡及的に追加しません。通常のC++ダンスをここで行い、プレーンな静的ライブラリまたはDLLプロジェクトにC++クラスを置き、.libsをリンクしてネイティブコードを共有できるようにする必要があります。 –

+0

@ HansPassant、私は今問題がC++/cliと関係がないことを知りました。申し訳ありませんが、これは明らかなようですが、私は完全にDLLとライブラリを使用しています。 C++クラスをプレーンな静的ライブラリやDLLプロジェクトに置き、.libsをリンクしてネイティブコードを共有できるようにする方法を教えてください。私がこれまでに試したことは、エラーを解決しなかった... –

答えて

2

C++/CLIを管理でき、管理対象外同じDLL内で一緒に暮らすためのコードですが、それぞれが引き続き通常使用するリンク機構を使用しています。

管理コードは、管理対象クラスをパブリックとマークし、アセンブリを参照としてロードすることによってリンクされます。アンマネージコードは、エクスポートDLLに__declspec(dllexport)、インポートDLL/EXEに__declspec(dllimport)を指定して関数をエクスポートすることによってリンクされます。

これをC++クラスとしてエクスポートする場合は、エラーメッセージに基づいて、すでに行っているように見える#include "CppClass.h"が必要です。これらの属性を指定する必要があります。それを行うための通常の方法は、ManagedProjectのプロジェクト設定ではプリプロセッサシンボルを定義し、OtherProjectでは定義しないで、__declspec(dllexport)または__declspec(dllimport)のいずれかに#を定義することです。

管理対象クラスにアンマネージクラスをラップし、.Netメカニズムを使用してリンクを処理する方法もあります。これにより、リンクが簡単になり、C++/CLIのために設計されたものと非常によく似ています(通常、ラッパーはC++/CLIではなくC#によって消費されます)。

+0

こんにちはDavid、私は助けに感謝します。 私はdllの使い方に慣れていません(私はまだC++とC++の新機能です)。 「ManagedProjectのプロジェクト設定でプリプロセッサシンボルが定義されていますか?」という手順を正確に実行するにはどうすればよいですか? 理想的には、CppClassをRefClassのラッパーとして使用したいので、管理対象外のプロジェクトからRefClassを使用できます。これを行うための推奨される方法は何ですか? –

+0

ああ、別の方法を行っている。私は自分でそれをやったわけではありませんが、.NETライブラリをロードするために管理されていないアプリケーションからマネージコードを呼び出す方法を調べることができ、 'gcroot'を使用してアンマネージドクラスにマネージオブジェクトラッピングしていること。 –

関連する問題