【发布时间】:2015-12-14 22:11:28
【问题描述】:
我有一个非托管类,它接受指向内存的指针作为其存储空间。
例如
class MemBlock
{
void* mpMemoryBlock;
// Various other variables that manipulate the memory block goes here.
public:
MemBlock( void* pMemoryBlock ) :
mpMemoryBlock( pMemoryBlock )
{
}
// A load of code that does operation on the memory block goes here.
};
现在我正在尝试包装这个类以便在 C# 中使用。显然,我希望能够将float[] 之类的东西传递给班级。显而易见的事情是使用包装类中的cli::pin_ptr。
public ref class MemBlockWrapper
{
MemBlock* mpMemBlock;
public:
MemBlockWrapper( array< float >^ fltArray )
{
cli::pin_ptr< float > pFltArray = &fltArray[0];
// Brilliant we can now pass this pinned array to the C++ code.
mpMemBlock = new MemBlock( (void*)pFltArray );
// Now the pin_ptr goes out of scope ...
}
}
但是,只要 cli::pin_ptr 在范围内,固定的 ptr 才有效。构造函数退出的那一刻,我不能再保证 C++ 类拥有的内存块是真实的。
有没有办法在类的生命周期内固定一个指针?我做了很多搜索,只找到了一种使用“GCHandle”的方法,该方法似乎纯粹用于托管 C++(即不是 C++/CLI)。有人可以向我指出一种确定性地固定和取消固定指针的方法吗?
【问题讨论】:
-
你不能让它成为一个类级别的字段吗?
-
@RonBeyer 不,它可能被 GC 移动,如果本机代码稍后访问指针,这可能会导致访问冲突。
-
@RonBeyer:不,
pin_ptr<T>是“魔法”,只能用于本地人。 "Pinning pointers can only be declared as non-static local variables on the stack. "
标签: c# .net c++-cli mixed-mode pin-ptr