[英]Why can't i see some C++ DLL ( support CLR ) in C# project ?
我编写了简单的C ++ Dll(win32),并将属性更改为“公共语言运行时支持(/ clr)”-
我创建了一个新的Simple winform项目(C#4.0),并创建了对C ++项目(C ++ DLL)的引用。
现在,我在C#项目中看不到C ++ dll-我无法使用它,我也不知道为什么。
您在C ++ dll中创建的类型仍然是本机的。 您需要将它们显式声明为托管类型。 例如:
ref class SomeType { }
声明一个托管类(请注意ref
关键字)。 这并不是那么容易。 您的本机代码不会神奇地转换为托管代码(一些基本数据类型,例如int
,但不是std::string
类的东西)。 如果您真的想充分利用C ++ / CLI进行互操作,则应该花一些时间来学习语法差异。
例如,如果您具有以下非托管功能:
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;
}
}
};
使用此类,您可以使用foo(UnamangedString(myManagedString))
调用void foo(LPCSTR pszText)
类的函数。 更复杂的是您必须执行的调用以及要编写的互操作代码。
注意:简单地将1:1托管接口暴露给非托管函数将使您的C#代码难以阅读,我建议您编写一个真正的OO接口以隐藏基础实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.