2013-07-13 8 views
8

Non riesco a capire come restituire un array da una DLL C++ esportata al mio programma C#. L'unica cosa che ho trovato su google è stata l'utilizzo di Marshal.Copy() per copiare l'array in un buffer, ma questo non mi dà i valori che sto cercando di restituire, non so cosa mi stia dando.Restituisce array C++ a C#

Ecco quello che ho provato:

funzione esportata:

extern "C" __declspec(dllexport) int* Test() 
{ 
    int arr[] = {1,2,3,4,5}; 
    return arr; 
} 

C# parte:

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

    static void Main(string[] args) 
    { 

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


    } 

So che il tipo di ritorno int [] è probabilmente sbagliato a causa della differenze gestite/non gestite, non ho proprio idea di dove andare da qui. Non riesco a trovare una risposta per nulla se non restituire array di caratteri a stringhe, non array interi.

Ho immaginato il motivo per cui i valori che ricevo con Marshal.Copy non sono quelli che sto restituendo è perché l'array 'arr' nella funzione esportata viene eliminato ma non sono sicuro al 100%, se qualcuno può chiarire che sarebbe grandioso.

+0

http://stackoverflow.com/questions/3776485/marshal-c-int-array-to-c-sharp Questo può aiutare –

+1

[Non va bene.] (Http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessible-outside-its-scope) – chris

+0

Grazie Chris, ero così preso da questo che ho dimenticato quello che stavo facendo. Ho intenzione di cambiare il mio codice un po ', in questo modo ho la mia funzione esportata prendere l'indirizzo in un buffer e riempire il buffer da lì. – David

risposta

10

Ho implementato la soluzione che Sriram ha proposto. Nel caso qualcuno lo voglia eccolo qui.

In C++ si crea una DLL con questo codice:

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; 
} 

La DLL si chiamerà InteropTestApp.

Quindi si crea un'applicazione console 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); 
      ptr = IntPtr.Add(ptr, 4); 
      int[] result = new int[arrayLength]; 
      Marshal.Copy(ptr, result, 0, arrayLength); 

      ReleaseMemory(ptr); 

      Console.ReadKey(); 
     } 
    } 
} 

result ora contiene i valori 1,2,3,4,5.

Spero che questo aiuti.

+3

Non aiuta. Dovrai mostrare come conosci il magico "5" e come rilascerai l'array in modo che non vi siano perdite di memoria permanenti. –

+3

@Hans, la domanda era "Restituisci array C++ a C#". Quindi, sì, aiuta. – user1764961

+4

Ok, allora considera il commento un avvertimento di ammonimento agli innumerevoli googler che troveranno la tua risposta un giorno e non hanno idea che il codice scarichi la memoria come un setaccio e bombarda arbitrariamente con violazioni di accesso. –