为什么我在C#项目中看不到一些C ++ DLL(支持CLR)?

我写了简单的C ++ Dll(win32),我将属性更改为’Common Language Runtime Support(/ clr)’ –

我创建了新的Simple 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(_unicodePtr.ToPointer()); } operator LPCSTR() { if (_content == nullptr) return NULL; Free(); _ansiPtr = Marshal::StringToHGlobalAnsi(_content); return reinterpret_cast(_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; } } }; 

使用此类,您可以使用foo(UnamangedString(myManagedString))调用类似void foo(LPCSTR pszText)的函数。 更复杂的是你必须做的调用以及你必须编写的更多代码才能在它们之间进行互操作。

注意:简单地将1:1托管接口暴露给非托管函数会使您的C#代码更难阅读,我建议您编写一个真正的OO接口来隐藏底层实现。

您在C ++ dll中创建的类型仍然是本机的。 您需要将它们显式声明为托管类型。 例如:

 ref class SomeType { } 

声明一个托管类(注意ref关键字)。 虽然不是那么容易。 您的本机代码不会神奇地转换为托管代码(一些基本数据类型,如int ,但不是像std::string这样的东西)。 如果您真的想充分利用C ++ / CLI进行互操作,那么您应该花时间了解语法差异。