如何在托管(C#)和非托管(C+;+;)代码之间来回传递数组内容 我试图把一组浮点从C ^传递到C++ DLL,这样会对数组进行一些工作,然后以浮点数组的形式传递答案(不一定是相同长度)。

如何在托管(C#)和非托管(C+;+;)代码之间来回传递数组内容 我试图把一组浮点从C ^传递到C++ DLL,这样会对数组进行一些工作,然后以浮点数组的形式传递答案(不一定是相同长度)。,c#,c++,arrays,marshalling,C#,C++,Arrays,Marshalling,我有一些代码将传递数组,修改它,然后返回它,但是数组中的值并不像预期的那样,尽管数组在其他方面格式良好… 下面的示例使用一组浮点数,将其传递给C++。在C++中,数组的每个元素都加上2的值,以模拟完成的工作,并使用回调将结果返回到C。 每次都会返回一组不同的值。 一组典型的返回值是:- 81.58881,2,75.75787,4 如果您有任何想法,我们将不胜感激。 干杯 格雷厄姆 C# C++ typedef void(__stdcall * CallBack1)(float * arr, in

我有一些代码将传递数组,修改它,然后返回它,但是数组中的值并不像预期的那样,尽管数组在其他方面格式良好…
下面的示例使用一组浮点数,将其传递给C++。在C++中,数组的每个元素都加上2的值,以模拟完成的工作,并使用回调将结果返回到C。 每次都会返回一组不同的值。
一组典型的返回值是:- 81.58881,2,75.75787,4

如果您有任何想法,我们将不胜感激。
干杯
格雷厄姆

C#

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);
}
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);
}
typedef void(u stdcall*CallBack1)(float*arr,int len);
__declspec(dllexport)无效测试端口(回调1 cb、浮点*arr、整数)
{
对于(int i=0;i
更新

我添加了一个临时的代码<代码>浮点<代码>来读取C++的数组内容,我发现数组C++的内容与传递的值没有关系,我不知道为什么……/p>< p>我已经设法使事情正常工作了。 我更改了GCHandle.Alloc方法,使其成为一个固定的对象指针,一切正常。
我还删除了testcallback函数中不必要的GCHandle调用 完全更改的代码为:-

C#

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);
}
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);
}
typedef void(u stdcall*CallBack1)(float*arr,int len);
__declspec(dllexport)无效测试端口(回调1 cb、浮点*arr、整数)
{
对于(int i=0;i
感谢Carlos和rhughes的帮助
干杯

Graham

可能在C++中添加一些诊断打印。只想看看数组在边界的前后有什么。如果你在Windows上开发,你试过用VisualStudio调试这个,并从C++中进入C++吗?是的,调试和诊断输出都是促使更新的原因。我还将C#side dllimport定义更改为:-public static extern void testcpluside(CallBack1 cb[MarshalAs(UnmanagedType.LPArray)]float[]x,int len);它正确地传递了数据,但在C++中调用回调时出现System.ExecutionEngineeException错误。这是一条过时的错误消息,指示运行时出现未指定的致命错误…这是不必要的,pinvoke封送拆收器已经确保在本机代码运行时固定数组。只需将参数声明为
float[]
。如果本机代码存储指针,并且回调在testcpluside()完成后发生,那么您就会遇到需要保持数组对象活动并固定的问题。一些你总是想避免的事情,钉住对GC来说是痛苦的。它被固定的时间越长,情况就越糟。嗨,汉斯,对不起,宣布哪个参数为float?在上面的评论中,我探讨了声明:-public static extern void testcpluside(CallBack1 cb[MarshalAs(UnmanagedType.LPArray)]float[]x,int len);这会导致在使用回调时非托管代码中出现错误——公平地说,这是一个调试器错误。请你把你所说的再详细一点好吗?