2012-04-10 6 views
5

Ich habe dies in meiner dll in C++ erstelltHandhabung Array zurückgegeben von C++ dll C#

extern "C" __declspec(dllexport) 
    char* __stdcall hh() 
{ 
    char a[2]; 
    a[0]='a'; 
     a[1]='b'; 
    return(a); 
} 

Und das ist, wie ich versuche, Code in C#

[DllImport(@"mydll.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]  
     public static extern IntPtr hh(); 
     static void Main(string[] args) 
     { 
      IntPtr a = hh(); 
      //How to proceed here??? 
     } 


    } 

Hilfe in Verfahren zu handhaben des Weiteren.

+0

Was genau ist Ihre Frage? –

+0

Ich möchte das Array returend aus C++ Code in C# – pushE

Antwort

-2

Versuchen Sie, nicht leeren StringBuilder als Rückgabewert zu verwenden.

1

wäre die Antwort

string stra = Marshal.PtrToStringAnsi(a); 

sein, aber Sie haben auch das Problem, dass die dll Müll pro Code als char * gibt einen Stil-String lokaler c ist. wäre ok, wenn Sie so etwas wie zurückkehren würde:

const char* str = "Hello from DLL."; 
+0

Ich möchte Array von Strings nicht eine einzige Zeichenfolge übergeben – pushE

+0

Ok. Das bisschen missverstanden. Hoffnung hilft trotzdem. – ervinbosenbacher

3

Es gibt keine Möglichkeit, solche Anordnungen zu behandeln. char a[2] ist auf dem Stapel in Ihrer C++ - Funktion zugeordnet und wird zerstört, sobald Sie von ihm zurückkehren. Sie sollten entweder ein Array aus C# übergeben und es in den C++ - Code einfügen oder ein Array im Heap zuweisen und einige Mittel bereitstellen, um es freizugeben.

Wenn Sie es richtig haben, hängt die Handhabung davon ab, wie Sie die Daten aus C++ - Code zurückgeben. Wenn es noch IntPtr ist, können Sie Marshal.ReadByte-Methoden verwenden, um Zeichen aus dem Speicher zu lesen, und Codierungsmethoden verwenden, um diese Bytes bei Bedarf in Zeichenfolgen umzuwandeln.

 

const int bufferSize = 2; // suppose it's some well-known value. 
IntPtr p = ...; // get this pointer somehow. 
for (var i = 0; i != bufferSize; ++i) 
{ 
    var b = Marshal.ReadByte(p, i); 
    Console.WriteLine(b); 
} 
 
2

bekam ich eine Lösung wie folgt ::

UNSERE C++ Code geht wie

folgt
extern "C" __declspec(dllexport) 
    char** __stdcall hh() 
{ 
static char* myArray[3] = {"A1", "BB2", "CC3",}; 
    return myArray; 
} 

Und C# geht wie

folgt
[DllImport(@"ourdll.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]  
     public static extern IntPtr hh(); 
     static void Main(string[] args) 
     { 
      IntPtr a = hh(); 
      int j = 0; 
      string[] s=new string[100]; 
      do 
      { 
       s[j] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(a,4*j)); 
       j++; 
      } 
      while(s[j-1] != null); 
     } 

Das einzige Problem ist jetzt konfrontiert ist, dass wie können wir Größe des Arrays kennen , so dass in dieser Anweisung string [] s = neue Zeichenfolge [100]; wir müssen nicht unser Gedächtnis verschwenden.