【问题标题】:Get c++ pointer to c#获取指向 c# 的 c++ 指针
【发布时间】:2012-11-01 08:32:30
【问题描述】:

我有一个 c++ dll,它有一些外部函数。 它看起来像这样

//C++ Code
void GetData(byte * pData)
{
  byte a[] = {3,2,1};
  pData = a;
}

我已经在 C# 端使用此代码来获取数据:

//C# Code
[DllImport(UnmanagedDLLAddress)]
public static extern void GetData(ref IntPtr pData);

//and use it like
IntPtr pointer = IntPtr.Zero;
GetData(ref pointer);
byte[] data = new byte[3] // <===== think we know size
Marshal.Copy(pointer,data ,0,3);

但“指针”总是为零,所以 Marshal.Copy 抛出空异常 我在哪里做错了? 太棒了

【问题讨论】:

  • @billz : typedef unsigned char byte;
  • @mX64 改成static const.
  • @Pubby 不,它没有。如果它返回一个指向本地数组的指针,该数组将是 UB,但它没有。正如所写的那样,代码什么都不做。
  • @john 哦,只是修改了本地的pData。是的,它什么都不做,虽然看起来他的意图会涉及 UB。

标签: c# c++ extern intptr


【解决方案1】:

首先,您的 C++ 代码将数组放入堆栈。您需要以其他方式分配它,文档从这里开始:http://msdn.microsoft.com/en-us/library/aa366533%28VS.85%29.aspx

其次,pData 是一个“正常”值参数,实际上是一个局部变量。您分配给它,然后当函数返回时它会被遗忘。如果您希望它是“输出参数”返回一个值,您需要它是对指针的引用或指向指针的指针。如果要将数组内容实际复制到 pData 指向的缓冲区,则需要使用 #include &lt;cstring&gt; 中的 memcpy 函数。

【讨论】:

    【解决方案2】:

    实际上,就像 hyde 所说的,使用 pData 作为“out”参数。 因为它显然是引用类型而不是值类型,所以被调用的方法应该注意内存分配。我仅将“ref”用于值类型,例如整数 - 例如从非托管方法中获取数组的长度。

    这种方式对我来说很好,此外,我使用“cdecl”调用约定。

    IntPtr aNewIntArray;
    uint aNewIntArrayCount = 0;
    
    NativeMethods.getEntityFieldIntArray(out aNewIntArray, ref aNewIntArrayCount);
    
    int[] aNewIntArrayResult = new int[aNewIntArrayCount];
    Marshal.Copy(aNewIntArray, aNewIntArrayResult, 0, (int)aNewIntArrayCount);
    

    方法声明:

    [DllImport(SettingsManager.PathToDLL, EntryPoint = "getEntityFieldIntArray", CallingConvention = CallingConvention.Cdecl)]
    public static extern ErrorCode getEntityFieldIntArray(out IntPtr aNewIntArray, ref UInt32 aNewIntArrayCount);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 2019-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多