【发布时间】:2020-12-06 13:33:57
【问题描述】:
我正在尝试将一个浮点数组从 C# 传递给一个 C++ dll,该 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, 0, 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++ 端的内容与传递的值没有关系 - 我不知道为什么....
【问题讨论】:
-
可能值得在 c++ 中添加一些诊断打印。只是为了看看数组在边界那一侧之前和之后的内容。
-
如果您在 Windows 上开发,您是否尝试过使用 Visual Studio 进行调试并从 C# 步入 C++?
-
是的 - 对于调试和诊断输出 - 这就是促使更新的原因。我还将 C# 端 dllimport 定义更改为:- public static extern void testCPlusSide(CallBack1 cb, [MarshalAs(UnmanagedType.LPArray)] float[] x, int len);它正确传递了数据,但在 C++ 中调用回调时给出了 System.ExecutionEngineException 错误
-
显然这是一条过时的错误消息,表明运行时出现未指定的致命错误...
标签: c# c++ arrays marshalling