【发布时间】:2018-12-25 05:00:47
【问题描述】:
在下面的示例中,C++ 中定义的dataArray 如果定义为数组,则可以工作,但不能作为指针(只是变成垃圾数据)。是否有另一种方法来编组 C# 数组,以便将指针作为数组读取?
C#
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CSharpFoo{
int alpha;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5]
public int[] dataArray;
int beta;
}
C++
struct CPPFoo{
int alpha;
//int* dataArray; //Doesn't work, even though initialized to an array elsewhere
int dataArray[5];
int beta;
}
通过这样的函数传递
C#
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true)]
public extern static bool InitializeDLL([MarshalAs(UnmanagedType.FunctionPtr)] ResultCallback callbackPointer);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void ResultCallback(CSharpFoo value);
C++
//Callback
typedef void(__stdcall * ResultCallback)(CPPFoo);
__declspec(dllexport) bool InitializeDLL(ResultCallback callback);
提前致谢!
编辑:: 因为“初始化到别处的数组”不清楚:
CPPFoo(int dummy){ //Constructor
alpha = 32;
dataArray = new int[5];
for (int i = 0; i < 5; i++){
dataArray[i] = i;
}
beta = 13;
}
//dataArray C++ {0,1,2,3,4}
//alpha C# 32
//dataArray C# {Total random garbage} (dataArray[3] is 13!)
//beta C# 0
PS,CPPFoo 结构是一个来自 DLL 的复杂结构,所以我无法更改它。现在,为了让事情正常进行,我将它复制到一个更合适的数组中,比如 NonCreature0714 的答案,但这会导致所有数据都被复制 - 两次。这是我试图避免的双重副本。
另一个编辑: 虽然看起来对于包含单个数组的结构,值可以正确传递,但对于复杂的结构,垃圾会被扔进去。 我更新了代码以反映更复杂的结构!
【问题讨论】:
-
请定义“不起作用”。
-
垃圾数据。现在将编辑
-
int* dataArray;-- 对我们来说,这是垃圾数据。我们不知道这个指针指向什么,因为它是未初始化的。也许您认为您将其设置为一个局部变量(因此不再存在)。 -
在别处初始化为数组?我从一个单独的 DLL 接收它,文档将它称为指向数组的指针。
-
@NonCreature0714 因为它不仅仅是 1 个数组,它是一个复杂的结构,包含从 DLL 接收的数据(所以我无法更改它)
标签: c# c++ marshalling