質問のように、Creating simple c++.net wrapper. ステップバイステップ
.NET で C++ クラスを使用しようとしていますが、Visual Studio (2008) でのビルドに問題があります。
アンマネージ クラス A (/clr でコンパイルされた C++) があります。A をラップし、A のメソッドに一致するメソッド デリゲートを持つ C++/clr クラス 'Class1' を作成しました。
クラス A のユニット ソース ファイルを Class1 (マネージ) のクラス ライブラリ プロジェクトに含めると、すべてのリンクに問題はなく、正常に動作しますが、A のような多くのアンマネージ C++ クラスがあり、それらを DLL に入れてリンクしようとしています。 (クラス ラッパーの) マネージ ライブラリへの DLL。[実際には、この時点でこれらの DLL をリンクする必要はないと思いますが、コンパイラがそれを要求しているようで、以下に示す同じエラーが発生します。]
VisualC++ / CLR / クラス ライブラリを作成し、C++ クラス (下記の A) を追加してビルドしました。[既定の設定を使用しましたが、プロジェクト リンカの設定で、[はい] と [いいえ] の両方で [出力の登録] を試しました。] エラーは発生せず、.DLL ファイルが作成されました。
VisualC++ / CLR / クラス ライブラリを作成し、ラッパー クラス 'Class1' を作成しました。すべてデフォルト設定を使用しました。プロジェクトのプロパティで、[参照] の [新しい参照の追加] をクリックし、最初の手順で作成した DLL を選択しました。
リンカー エラーが発生します。
test_NET_library.obj : error LNK2028: unresolved token (0A000009) "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2028: unresolved token (0A00000A) "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
C:\temp\test_Cpp_CLI\test_NET_library\Debug\test_NET_library.dll : fatal error LNK1120: 4 unresolved externals
ラッパー クラス ライブラリ プロジェクトで A.cpp を削除した場合と同じエラー (機能するオプション)。これはプログラムではなくライブラリであるため、ビルドがそもそも外部を解決しようとする理由がわかりません。
ラッパー クラス ライブラリ プロジェクトのプロパティに追加したり、アンマネージ クラスの DLL やコンパイラ オプションを登録したりする必要があるものはありますか? DLL と一緒に .lib ファイルも必要ですか? (プロジェクトのターゲット ディレクトリに lib ファイルは表示されません)
__declspec(dllexport) を使用する必要がありますか [それは、クラス メンバーではなく、C スタイルの関数のみであると考えられていました] 。 アンマネージ C++ ライブラリが CLR を有効にしてコンパイルされている場合でも。
(スタティック ライブラリとしてコンパイルも試みましたが、.lib ファイルを CLR クラス ライブラリ プロジェクトに追加する方法がわかりません)。
私のテストクラスは
namespace Z
{
class A
{
public:
int m1(int p1, int p2);
int m2(int p3, int p4);
};
};
実装で:
#include "A.h"
namespace Z
{
int A::m1(int p1, int p2) { return p1+p2; };
int A::m2(int p3, int p4) { return p3 * p4; };
};
そしてラッパークラスは
#pragma once
#include "../A.h"
using namespace System;
namespace test_NET_library {
public ref class Class1
{
private: Z::A *a;
public: Class1()
: a(new Z::A)
{}
public: inline int m1(int p1, int p2)
{ return a->m1(p1,p2);
};
public: inline int m2(int p3, int p4)
{return a->m2(p3,p4);
};
};
}
質問に従って: C++/CLI 混合モード DLL の作成 私も試しました:
#pragma managed(push, off)
#include "../A.h"
#pragma managed(pop)
また、このプッシュは A.cpp の周りで管理されています。
更新: mcdave の応答に従って、/clr を削除すると DLL が生成されました。この DLL を test_NET_library で使用できるようにするにはどうすればよいですか?
References/Add New Reference を試し、新しいこの新しい DLL を選択しました。「.NET アセンブリでも登録済みの ActiveX コントロールでもないため、ファイル 'C:..\unmanaged_lib.dll' への参照を追加できませんでした。」というメッセージが表示されました。DLL はプロジェクトのファイル リストに追加されましたが、コンパイラはそれを無視しているようです。
Add/Existing item を試し、新しい DLL を選択しました。ただし、.DLL ファイルは選択可能なファイル タイプではありません。