C++ cli 如何创建自记忆钉扎C++/CLI类? 我在C++库中创建一个.NET包装器(我没有访问源代码),使用C++ +CLI。C++库需要调用在C++中使用的.NET委托。我使用McHal::GETFrimePoTeFrExtReATE给C++库类赋值调用函数。但是,当从非托管端回调此函数时,我需要确保.NET委托函数仍位于同一内存位置
当然,最简单的方法是要求.NET库用户锁定.NET对象,但这并不是一个真正干净的设计,还允许用户射中自己的脚。更好的方法是设计.NET类,使其在创建时或由函数/事件触发时固定自身 我该如何设计这个?根据此链接,不能将内部~=固定指针作为对象成员。因此,这意味着可以将固定指针引用创建为静态变量或全局变量 所以我想做这两件事中的任何一件,但无法让它编译/工作C++ cli 如何创建自记忆钉扎C++/CLI类? 我在C++库中创建一个.NET包装器(我没有访问源代码),使用C++ +CLI。C++库需要调用在C++中使用的.NET委托。我使用McHal::GETFrimePoTeFrExtReATE给C++库类赋值调用函数。但是,当从非托管端回调此函数时,我需要确保.NET委托函数仍位于同一内存位置,c++-cli,C++ Cli,当然,最简单的方法是要求.NET库用户锁定.NET对象,但这并不是一个真正干净的设计,还允许用户射中自己的脚。更好的方法是设计.NET类,使其在创建时或由函数/事件触发时固定自身 我该如何设计这个?根据此链接,不能将内部~=固定指针作为对象成员。因此,这意味着可以将固定指针引用创建为静态变量或全局变量 所以我想做这两件事中的任何一件,但无法让它编译/工作 public ref class UserClass{ void createDotNetCPPWrapperClass() { m_
public ref class UserClass{
void createDotNetCPPWrapperClass()
{
m_class = gcnew DotNetCPPWrapperClass;
}
DotNetCPPWrapperClass^ m_class
};
public ref class DotNetCPPWrapperClass{
static pin_ptr<DotNetCPPWrapperClass^> pinnedSelf;
DotNetCPPWrapperClass()
{
pinnedSelf = this;
}
};
public ref class UserClass{
void createDotNetCPPWrapperClass()
{
m_class=gcnew DotNetCPPWrapperClass;
}
DotNetCPPWrapperClass ^m_类
};
公共引用类DotNetCPPWrapperClass{
静态引脚ptr钉扎自身;
DotNetCPPWrapperClass()
{
pinnedSelf=这个;
}
};
或
public ref class UserClass{
void createDotNetCPPWrapperClass()
{
m_class=gcnew DotNetCPPWrapperClass;
m_class->setupImportantstStuff();
}
DotNetCPPWrapperClass ^m_类
};
公共引用类DotNetCPPWrapperClass{
静态引脚ptr钉扎自身;
DotNetCPPWrapperClass(){}
void setupimportantsttuff()
{
pinnedSelf=这个;
}
};
GCHandle
将解决您的问题
public ref class Wrapper
{
GChandle thisHandle;
public:
Wrapper()
{
thisHandle = GCHandle.Alloc(this, GCHandleType::Normal);
}
~Wrapper() // Dispose
{
if(thisHandle.IsAllocated)
thisHandle.Free;
}
!Wrapper() // Finalize
{
//Native resource releasing
}
}
现在有几点需要注意
GCHandleType::Normal
分配句柄不仅使其不可收集,而且使其可移动李>
delete
操作符,在C#中调用Dispose()
并释放句柄是非常重要的。如果忘记调用这些,整个对象将成为内存泄漏您是否研究过使用框架提供的
GCHandle
或HandleRef
结构?使用Marshal::GetFunctionPointerForDelegate()的要点是您不必这样做。不要帮忙,请详细说明。“您必须手动防止垃圾收集器从托管代码收集委托。垃圾收集器不会跟踪对非托管代码的引用。”或者您是说GetFunctionPointerForDelegate将阻止重新定位,而不是垃圾收集?
public class MyClass {
private GCHandle gch;
public MyClass() {
gch=GCHandle.Alloc(this, GCHandleType.Pinned);
}
}
public ref class Wrapper
{
GChandle thisHandle;
public:
Wrapper()
{
thisHandle = GCHandle.Alloc(this, GCHandleType::Normal);
}
~Wrapper() // Dispose
{
if(thisHandle.IsAllocated)
thisHandle.Free;
}
!Wrapper() // Finalize
{
//Native resource releasing
}
}