问题描述
我正在尝试将浮点数数组从C#传递到C ++ dll,该函数将对该数组进行一些工作,然后以浮点数数组的形式(不一定长度相同)返回答案。
我有将通过该数组,对其进行修改然后返回的代码,但是该数组中的值与预期不符,尽管该数组看上去格式正确。
下面的示例采用一个浮点数组,并将其传递给C ++。在C ++中,将2的值添加到数组的每个元素以模拟完成的工作,并使用回调将结果返回给C#。
每次都会返回一组不同的值。
典型的一组返回值是:
81.58881,2,75.75787,4
任何想法都会被感激。.
干杯
格雷厄姆
C#
public delegate void CallBack1(IntPtr param,int len);
[DllImport("TestDll.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern void testCPlusSide(CallBack1 cb,IntPtr arr,int len);
private void button_Click(object sender,EventArgs e)
{
float[] dataIn = new float[] { 0,0.5f,7.79f,46 };
GCHandle gch = GCHandle.Alloc(dataIn);
CallBack1 testCB = new CallBack1(TestCallBack);
testCPlusSide(testCB,GCHandle.ToIntPtr(gch),dataIn.Length);
gch.Free();
}
void TestCallBack(IntPtr param,int len)
{
float[] vals = new float[len];
GCHandle gch = GCHandle.FromIntPtr(param);
Marshal.copy(param,vals,len);
StringBuilder sb = new StringBuilder();
foreach (float item in vals)
{
sb.Append(item.ToString() + "\n");
}
MessageBox.Show(sb.ToString());
}
C ++
typedef void(__stdcall * CallBack1)(float * arr,int len);
__declspec(dllexport) void testCPlusSide(CallBack1 cb,float* arr,int len)
{
for (int i = 0; i < len; i++)
{
arr[i] += 2;
}
cb(arr,len);
}
更新
我添加了一个临时float
来在C ++端读取数组的内容,但我发现C ++数组的内容与传递的值没有任何关系-我不知道为什么....
解决方法
我设法使事情顺利进行。
我更改了GCHandle.Alloc方法,使之成为了固定对象指针,并且一切正常。
我还删除了TestCallBackFunction中不必要的GCHandle调用
更改后的完整代码为:-
C#
public delegate void CallBack1(IntPtr param,int len);
[DllImport("TestDll.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern void testCPlusSide(CallBack1 cb,IntPtr arr,int len);
private void button_Click(object sender,EventArgs e)
{
float[] dataIn = new float[] { 0,0.5f,7.79f,46 };
GCHandle gch = GCHandle.Alloc(dataIn,GCHandleType.Pinned);
CallBack1 testCB = new CallBack1(TestCallBack);
testCPlusSide(testCB,gch.AddrOfPinnedObject(),dataIn.Length);
gch.Free();
}
void TestCallBack(IntPtr param,int len)
{
float[] vals = new float[len];
Marshal.Copy(param,vals,len);
StringBuilder sb = new StringBuilder();
foreach (float item in vals)
{
sb.Append(item.ToString() + "\n");
}
MessageBox.Show(sb.ToString());
}
C ++
typedef void(__stdcall * CallBack1)(float * arr,int len);
__declspec(dllexport) void testCPlusSide(CallBack1 cb,float* arr,int len)
{
for (int i = 0; i < len; i++)
{
arr[i] += 2;
}
cb(arr,len);
}
感谢卡洛斯和修士的帮助
干杯
格雷厄姆