如何“固定” C++/CLI 指针
我正在包装一个读取自定义二进制数据文件并使数据可用于 .net/c# 类的类
,但是在代码的几行中,我开始收到内存访问冲突错误,我认为这是由于 GC 造成的移动内存,该类是托管的
这是 C# 中的调用代码 - reader 是混合代码(旧的非托管代码上的托管包装方法)
if ( ! reader.OpenFile(...) )
return ;
foreach(string fieldName in fields)
{
int colIndex = reader.GetColIndex( fieldName );
int colType = reader.GetColType( colIndex ); // error is raised here on 2nd iteration
}
for ( int r = 0 ; r < reader.NumFields(); r++ )
{
foreach(string fieldName in fields)
{
int colIndex = reader.GetColIndex( fieldName );
int colType = reader.GetColType( colIndex ); // error is raised here on 2nd iteration
switch ( colType )
{
case 0 : // INT
processField( r, fieldName, reader.GetInt(r,colIndex) );
break ;
....
}
}
}
....
Reader 有一个旧的非托管类实例引用,它将二进制数据保存在内存中 并且它是一个指针类型,因为托管类不能保存非托管类型
我已经查看了interior_ptr,pin_ptr,但它们给出了错误c3160不能在托管类中
任何解决方法?顺便说一句,这是我很长一段时间以来的第一个 C++ 程序!
更新 : 更新了问题,上面再次是调用代码和阅读器混合(托管+旧的非托管代码)
&是的,这些论点都是有效的
I am wrapping up a class which reading a custom binary data file and makes the data available to a .net/c# class
However a couple of lines down the code, i start getting the memory access violation error which i believe is due to the GC moving memory around, the class is managed
Here's the calling code in C# - reader is mixed code ( managed wrapper methods on old unmanaged code )
if ( ! reader.OpenFile(...) )
return ;
foreach(string fieldName in fields)
{
int colIndex = reader.GetColIndex( fieldName );
int colType = reader.GetColType( colIndex ); // error is raised here on 2nd iteration
}
for ( int r = 0 ; r < reader.NumFields(); r++ )
{
foreach(string fieldName in fields)
{
int colIndex = reader.GetColIndex( fieldName );
int colType = reader.GetColType( colIndex ); // error is raised here on 2nd iteration
switch ( colType )
{
case 0 : // INT
processField( r, fieldName, reader.GetInt(r,colIndex) );
break ;
....
}
}
}
....
Reader has an old unmanaged class instance reference which holds the binary data in memory
AND It's a pointer type since a managed class cannot hold an unmanaged type
i've looked at interior_ptr, pin_ptr but they give an error c3160 cannot be in a managed class
Any workaround ? BTW, this is my 1st C++ program in a very long time !
UPDATE :
updated the Q, again the above is the calling code and reader is mixed ( managed + old unmanaged code )
& yes the arguments are all valid
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据代码的描述“类被管理”,在我看来,这听起来不像是内存被移动。如果 reader 是托管类并且使用者是托管类,则它们的所有分配都在托管堆上,并且它们不调用任何非托管 API,则不需要固定。
听起来更像是您的
reader
类是混合模式 C++(托管加非托管代码)。在这种情况下需要注意的一些事情
在 c 运行时堆上并尝试
将其传递给托管代码?
类上分配一个缓冲区
托管堆并尝试将其传递给
非托管代码(这是您需要固定的地方)?
最近这个问题让我大吃一惊:
gcnew array(256)
那样被清零。 (最近,当我确信缓冲区应该为 NULL 时,花了几分钟试图弄清楚为什么free
在我面前爆炸,最近有一个重要的 DOH 时刻)Based on the description of your code "the class is managed" it doesn't sound to me like memory being moved around. If
reader
is a managed class and the consumer is a managed class, all of their allocations are on the managed heap, and they don't call any unmanaged APIs, pinning isn't necessary.It sounds more like your
reader
class is mixed mode C++ (managed plus unmanaged code).Some things to lookout for in that case
on the c runtime heap and trying to
pass it to managed code?
class allocating a buffer on the
managed heap and trying to pass it to
unmanaged code (this is where you need pinning)?
and this one which nailed me just recently:
gcnew array<Byte>(256)
would be. (Recently had a big DOH moment after a few minutes trying to figure out whyfree
was blowing up in my face when I thought for sure the buffer should beNULL
)