シンプルな C++ DLL ( win32 ) を作成し、プロパティを「共通言語ランタイム サポート (/clr)」に変更しました -
新しいシンプルな winform プロジェクト (C# 4.0) を作成し、C++ プロジェクト (C++ DLL) への参照を作成しました。
現在、C# プロジェクトに C++ dll が表示されません。使用できず、その理由もわかりません。
たとえば、このアンマネージ関数がある場合:
bool fooFunction(int firstParameter, int secondParameter);
マネージコードから見えるようにしたい場合は、マネージクラスにラップする必要があります(最初の簡単なステップとして)。
public ref class MyClass abstract sealed
{
public:
static bool Foo(int firstParameter, int secondParameter)
{
return fooFunction(firstParameter, secondParameter);
}
};
これは簡単な試験です。複雑なタイプと相互運用する必要がある場合は、それらすべてをラップする必要があります。たとえば、文字列を受け入れる関数と相互運用する必要がある場合は、これを管理する必要があります。通常、私は次のようなクラスを使用します。
ref class UnmanagedString sealed
{
public:
UnmanagedString(String^ content) : _content(content)
{
_unicodePtr = _ansiPtr = IntPtr::Zero;
}
~UnmanagedString()
{
Free();
}
operator LPWSTR()
{
if (_content == nullptr)
return NULL;
Free();
_unicodePtr = Marshal::StringToHGlobalUni(_content);
return reinterpret_cast<LPWSTR>(_unicodePtr.ToPointer());
}
operator LPCSTR()
{
if (_content == nullptr)
return NULL;
Free();
_ansiPtr = Marshal::StringToHGlobalAnsi(_content);
return reinterpret_cast<LPCSTR>(_ansiPtr.ToPointer());
}
virtual System::String^ ToString() override
{
return _content;
}
virtual int GetHashCode() override
{
return _content->GetHashCode();
}
virtual bool Equals(Object^ obj) override
{
return _content->Equals(obj);
}
private:
IntPtr _unicodePtr, _ansiPtr;
String^ _content;
void Free()
{
if (_unicodePtr != IntPtr::Zero)
{
Marshal::FreeHGlobal(_unicodePtr);
_unicodePtr = IntPtr::Zero;
}
if (_ansiPtr != ntPtr::Zero)
{
Marshal::FreeHGlobal(_ansiPtr);
_ansiPtr = IntPtr::Zero;
}
}
};
このクラスを使用すると、voidのような関数を。で呼び出すことができfoo(LPCSTR pszText)
ますfoo(UnamangedString(myManagedString))
。より複雑なのは、あなたがしなければならない呼び出しと、それらの間で相互運用するためにあなたが書かなければならないより多くのコードです。
注:1:1のマネージドインターフェイスをアンマネージド関数に公開するだけでは、C#コードが読みにくくなります。基になる実装を非表示にするために、真のOOインターフェイスを作成することをお勧めします。
C++ dll で作成した型はネイティブのままです。それらをマネージド型として明示的に宣言する必要があります。例えば:
ref class SomeType { }
マネージド クラスを宣言します (ref
キーワードに注意してください)。とはいえ、それほど簡単ではありません。ネイティブ コードが魔法のようにマネージ コードに変換されることはありません ( のようないくつかの基本的なデータ型は変換されますint
が、 のようなものは変換されませんstd::string
)。相互運用のために C++/CLI を最大限に活用したい場合は、時間をかけて構文の違いについて学習する必要があります。