将 C++ 数组返回到 C#

Posted

技术标签:

【中文标题】将 C++ 数组返回到 C#【英文标题】:Return C++ array to C# 【发布时间】:2013-07-12 03:37:36 【问题描述】:

我似乎不知道如何将一个数组从导出的 C++ DLL 返回到我的 C# 程序。我从谷歌搜索中发现的唯一一件事是使用 Marshal.Copy() 将数组复制到缓冲区中,但这并没有给我想要返回的值,我不知道它给了我什么。

这是我一直在尝试的:

导出函数:

extern "C" __declspec(dllexport) int* Test() 

    int arr[] = 1,2,3,4,5;
    return arr;

C#部分:

    [DllImport("Dump.dll")]
    public extern static int[] test();

    static void Main(string[] args)
    

        Console.WriteLine(test()[0]); 
        Console.ReadKey();


    

我知道返回类型 int[] 可能是错误的,因为托管/非托管的差异,我只是不知道从这里去哪里。除了将字符数组返回到字符串而不是整数数组之外,我似乎找不到任何答案。

我认为我使用 Marshal.Copy 获得的值不是我返回的值的原因是因为导出函数中的 'arr' 数组被删除了,但我不能 100% 确定,如果有人可以的话把这个弄清楚就好了。

【问题讨论】:

***.com/questions/3776485/…这可能对你有帮助 Not good. 谢谢 Chris,我太沉迷于此了,以至于忘记了自己在做什么。我将稍微更改一下我的代码,这样我导出的函数将地址输入到缓冲区并从那里填充缓冲区。 【参考方案1】:

我已经实施了 Sriram 提出的解决方案。万一有人想要它在这里。

在 C++ 中,您可以使用以下代码创建一个 DLL:

extern "C" __declspec(dllexport) int* test() 

    int len = 5;
    int * arr=new int[len+1];
    arr[0]=len;
    arr[1]=1;
    arr[2]=2;
    arr[3]=3;
    arr[4]=4;
    arr[5]=5;
        return arr;


extern "C" __declspec(dllexport) int ReleaseMemory(int* pArray)

    delete[] pArray;
    return 0;

DLL 将被称为InteropTestApp

然后你在 C# 中创建一个控制台应用程序。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace DLLCall

    class Program
    
        [DllImport("C:\\Devs\\C++\\Projects\\Interop\\InteropTestApp\\Debug\\InteropTestApp.dll")]
        public static extern IntPtr test();

        [DllImport("C:\\Devs\\C++\\Projects\\Interop\\InteropTestApp\\Debug\\InteropTestApp.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ReleaseMemory(IntPtr ptr);

        static void Main(string[] args)
        
            IntPtr ptr = test();
            int arrayLength = Marshal.ReadInt32(ptr);
            // points to arr[1], which is first value
            IntPtr start = IntPtr.Add(ptr, 4);
            int[] result = new int[arrayLength];
            Marshal.Copy(start, result, 0, arrayLength);

            ReleaseMemory(ptr);

            Console.ReadKey();
        
    

result 现在包含值 1,2,3,4,5

希望对您有所帮助。

【讨论】:

没用。你需要展示你是如何知道魔法“5”的,以及你将如何释放数组,这样就不会出现永久性的内存泄漏。 @Hans,问题是“将 C++ 数组返回到 C#”。所以,是的,它确实有帮助。 好的,那么就将评论视为对无数 google 员工的警示性警告,他们总有一天会找到您的答案,并且不知道代码会像筛子一样泄漏内存,并且会因访问违规而任意轰炸。跨度> @Gabriel 该代码不会泄漏内存。在 C++ 中分配的内存必须在 C++ 中删除。 C# 的 GC 对自身外部生成的内存一无所知。 @Gabriel 谢谢,我想这是因为我在完成 C# 代码之前调用了ReleaseMemory

以上是关于将 C++ 数组返回到 C#的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式单声道:将数组从 C# DLL 返回/复制到 C++

从 C# 到 C++ 并返回的数组,没有不安全的代码 [重复]

如何将结构数组从 c++ 传递到 c#?

从我的 c++ 应用程序调用 c# dll(解析 XML 文件)以将数组/列表返回给 c++

当 C# 调用 c++ 函数时,是不是可以在被调用的 c++ 函数中初始化数组并返回到 C#?

将对象数组从 C# 返回到 COM 中的 C