【问题标题】:Can't seem to get a non-zero IntPtr from a byte[] instance variable似乎无法从 byte[] 实例变量中获得非零 IntPtr
【发布时间】:2016-03-09 21:46:15
【问题描述】:

我发现许多方法可以从byte[] 获取IntPtr,所有这些方法我都可以成功地传递到外部非托管代码中,但只有如果我在堆栈上分配了byte[]。尝试对byte[] 实例变量执行相同操作,我得到null (IntPtr.Zero) 结果,无论我选择哪种获取IntPtr 的方法。在这种情况下,我没有找到任何关于实例变量的处理方式是否与堆栈上分配的变量不同的信息。

这是我想用来将有效的IntPtr 获取到byte[] 实例变量的方法:

GCHandle pinned = GCHandle.Alloc(outBytes, GCHandleType.Pinned);
IntPtr ptr = pinned.AddrOfPinnedObject();

// Always true, for reasons I'm unaware.
if (ptr == IntPtr.Zero) {}

pinned.Free();

谢谢!

【问题讨论】:

  • “在堆栈上”是指stackalloc
  • 我的意思是在本地范围内声明一个字节[],如下所示:byte[] outBytes = new byte[GetNumBytes()]。考虑到我使用的是new,我的术语可能不正确。
  • 你能举一个不起作用的代码示例吗?它是一个全局数组吗?对象的成员?传递给函数的引用?
  • 如果outBytes 是对象(实例变量)的成员,则IntPtr ptr 为零。我会稍微充实一下我的问题中的代码。
  • 不相关,但考虑使用 try-finally 子句以确保 pinned.Free() 始终运行,即使您的封送代码抛出异常。否则你可能会泄露内存。

标签: c# pointers pinvoke


【解决方案1】:

GCHandle.Alloc( thing, GCHandleType.Pinned ) 产生IntPtr.Zero 句柄的唯一时间是thing 为空。

当您提供给GCHandle.Alloc() 时,您的字节数组引用为空。

这里是它返回零的地方:

public class ZeroTest
{
    private byte[] someArray;

    public Test()
    {
        this.someArray = null;
    }

    public void DoMarshal()
    {
        GCHandle handle = GCHandle.Alloc( this.someArray, GCHandleType.Pinned );

        try
        {
            // Prints '0'.
            Console.Out.WriteLine( handle.AddrOfPinnedObject().ToString() );
        }
        finally
        {
            handle.Free();
        }
    }
}

这里是它返回非零的地方:

public class Test
{
    private byte[] someArray;

    public Test()
    {
        this.someArray = new byte[1];
    }

    public void DoMarshal()
    {
        GCHandle handle = GCHandle.Alloc( this.someArray, GCHandleType.Pinned );

        try
        {
            // Prints a non-zero address, like '650180924952'.
            Console.Out.WriteLine( handle.AddrOfPinnedObject().ToString() );
        }
        finally
        {
            handle.Free();
        }
    }
}

【讨论】:

  • 再次检查我的代码以充实我上面的代码确实向我揭示了我的错误。在我希望初始化成员变量的地方,我声明了一个局部变量,所以我的成员变量确实是null。我想我应该吃点东西...谢谢你的帮助!
猜你喜欢
  • 2016-09-14
  • 2018-02-25
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 2017-04-27
相关资源
最近更新 更多