如何“固定” C++/CLI 指针

发布于 2024-09-05 03:56:23 字数 1117 浏览 4 评论 0原文

我正在包装一个读取自定义二进制数据文件并使数据可用于 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听你说爱我 2024-09-12 03:56:23

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

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

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

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

最近这个问题让我大吃一惊:

  • 如果您有非托管 C++ 代码,您是否会将所有缓冲区分配清空?从 c 运行时堆进行 malloc 的任意字节数组不会像 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

  • Is your C++ class allocating a buffer
    on the c runtime heap and trying to
    pass it to managed code?
  • Is your C++
    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:

  • If you have unmanaged C++ code are you null-ing all of your buffer allocations? An arbitrary array of bytes malloc-ed from the c-runtime heap is not nulled out the way a gcnew array<Byte>(256) would be. (Recently had a big DOH moment after a few minutes trying to figure out why free was blowing up in my face when I thought for sure the buffer should be NULL)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文