简体   繁体   English

获取指向C#的C ++指针

[英]Get c++ pointer to c#

i have a c++ dll ,that has some extern function. 我有一个C ++ dll,具有某些外部功能。 and its look like this 它看起来像这样

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

and i have use this code in C# side to get data : 我已经在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);

but always "pointer" is zero so Marshal.Copy throw null exception where i did mistake ? 但始终“指针”为零,所以Marshal.Copy抛出空异常,我在哪里出错? ty ty

First, your C++ code puts the array to the stack. 首先,您的C ++代码将数组放入堆栈。 You need to allocate it some other way, for documentation start from here: http://msdn.microsoft.com/en-us/library/aa366533%28VS.85%29.aspx 您需要以其他方式分配它,以便文档从此处开始: http : //msdn.microsoft.com/zh-cn/library/aa366533%28VS.85%29.aspx

Second, pData is a "normal" value argument, effectively a local variable. 其次,pData是一个“普通”值参数,实际上是一个局部变量。 You assign to it, then it gets forgotten when function returns. 您分配给它,然后在函数返回时将其忘记。 You need it to be reference to pointer or pointer to pointer if you want it to be "out parameter" returning a value back. 如果希望它成为“返回参数”并返回一个值,则需要它作为对指针的引用或对指针的指针。 If you want to actually copy the array contents to the buffer pointed to by pData, then you need to use memcpy function from #include <cstring> . 如果要实际将数组内容复制到pData指向的缓冲区中,则需要使用#include <cstring> memcpy函数。

Actually, like hyde told, use pData as "out" parameter. 实际上,就像海德所说的那样,将pData用作“输出”参数。 Because it's obviously a reference type and no value type, the called method shall take care about memory allocation. 因为它显然是引用类型而没有值类型,所以被调用的方法应注意内存分配。 I used "ref" only for value types, like integer - eg getting the length of the array from the unmanaged method. 我仅将“ ref”用于值类型,例如整数-例如,从非托管方法获取数组的长度。

This way works fine for me, furthermore, i use the "cdecl" calling convention. 这种方式对我来说很好用,此外,我使用“ cdecl”调用约定。

IntPtr aNewIntArray;
uint aNewIntArrayCount = 0;

NativeMethods.getEntityFieldIntArray(out aNewIntArray, ref aNewIntArrayCount);

int[] aNewIntArrayResult = new int[aNewIntArrayCount];
Marshal.Copy(aNewIntArray, aNewIntArrayResult, 0, (int)aNewIntArrayCount);

method declaration: 方法声明:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM