I can't seem to figure out how to return an array from an exported C++ DLL to my C# program. The only thing I've found from googling was using Marshal.Copy() to copy the array into a buffer but that doesn't give me the values I'm trying to return, I don't know what it's giving me.
Here's what I've been trying:
Exported function:
extern "C" __declspec(dllexport) int* Test() 
{
    int arr[] = {1,2,3,4,5};
    return arr;
}
C# portion:
    [DllImport("Dump.dll")]
    public extern static int[] test();
    static void Main(string[] args)
    {
        Console.WriteLine(test()[0]); 
        Console.ReadKey();
    }
I know the return type int[] is probably wrong because of the managed/unmanaged differences, I just have no idea where to go from here. I can't seem to find an answer for anything but returning character arrays to strings, not integer arrays.
I figured the reason the values I'm getting with Marshal.Copy are not the ones I'm returning is because the 'arr' array in the exported function gets deleted but I'm not 100% sure, if anyone can clear this up that would be great.
I have implemented the solution Sriram has proposed. In case someone wants it here it is.
In C++ you create a DLL with this code:
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;
}
The DLL will be called InteropTestApp.
Then you create a console application in 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 now contains the values 1,2,3,4,5.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With