【问题标题】:How to "pin" C++/CLI pointers如何“固定”C++/CLI 指针
【发布时间】:2010-06-09 17:12:11
【问题描述】:

我正在封装一个读取自定义二进制数据文件并使数据可用于 .net/c# 类的类

然而,在代码下面几行,我开始收到内存访问冲突错误,我认为这是由于 GC 移动内存造成的,该类是托管的

这是 C# 中的调用代码 - 阅读器是混合代码(旧的非托管代码上的托管包装方法)

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 有一个旧的非托管类实例引用,它将二进制数据保存在内存中 AND 它是指针类型,因为托管类不能拥有非托管类型

我查看了interior_ptr、pin_ptr,但它们给出了错误c3160 cannot be in a managed class

任何解决方法?顺便说一句,这是我很长一段时间以来的第一个 C++ 程序!

更新: 更新了Q,再次上面是调用代码和阅读器混合(托管+旧的非托管代码)

& 是的,参数都是有效的

【问题讨论】:

  • 是 C++ 的读者吗?上面的代码看起来更像是带有 foreach 而不是 for each 的 C#。
  • reader 是什么类型?它是托管类型吗? colType 的值是多少?它是一个有效值吗?
  • foreach 是 C# 关键字还是您使用的是 boost 库? AFAIK,C++ 没有 foreach 关键字,这意味着你不是用 C++ 编写的!
  • @Thomas 新的 C++/CLI 具有“for each(.. in ..)”blogs.msdn.com/b/arich/archive/2004/09/08/227139.aspx
  • 错误所在的位置,不在此代码中。用 C++/CLI 代码破坏堆并不难。

标签: visual-c++ visual-studio-2008 garbage-collection c++-cli


【解决方案1】:

根据您的代码描述“类是托管的”,这听起来不像是内存在移动。如果reader 是托管类而消费者是托管类,则它们的所有分配都在托管堆上,并且它们不调用任何非托管API,则不需要固定。

听起来您的 reader 类更像是混合模式 C++(托管代码和非托管代码)。

在这种情况下需要注意的一些事项

  • 您的 C++ 类是否分配了缓冲区 在 c 运行时堆上并试图 将其传递给托管代码?
  • 是你的 C++ 类分配缓冲区 托管堆并尝试将其传递给 非托管代码(这是您需要固定的地方)?

还有这个最近让我很受打击的:

  • 如果您有非托管 C++ 代码,您是否会将所有缓冲区分配都归零?从 c 运行时堆中分配的任意字节数组不会像 gcnew array&lt;Byte&gt;(256) 那样被清空。 (最近有一个重要的 DOH 时刻,几分钟后试图弄清楚为什么 free 在我确定缓冲区应该是 NULL 时在我脸上炸毁)

【讨论】:

    猜你喜欢
    • 2013-01-05
    • 2011-10-16
    • 1970-01-01
    • 2010-11-19
    • 2011-08-28
    • 2021-08-14
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多