2012-04-10 12 views
5

mam to w moim DLL utworzonego w C++Postępowanie Array wrócił z C++ dll do C#

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

i to jest jak próbuję obsłużyć kod w 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??? 
     } 


    } 

Pomoc w postępowaniu dalej.

+0

Na czym dokładnie polega twoje pytanie? –

+0

Chcę wydrukować tablicę returend z kodu C++ w c ​​# – pushE

Odpowiedz

-2

Staraj się nie używać pustego StringBuildera jako wartości zwracanej.

1

Odpowiedź byłaby

string stra = Marshal.PtrToStringAnsi(a); 

Ale trzeba też problem, że dll zwraca śmieci za kodzie jako char * jest lokalnym ciąg c styl. byłoby ok gdyby wrócisz coś takiego:

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

Chcę przekazać tablicę ciągów nie jeden ciąg – pushE

+0

Ok. Źle to zrozumiałem. Nadzieja i tak pomaga. – ervinbosenbacher

3

nie ma sposobu, aby radzić sobie w takich tablic. char a[2] jest przydzielany na stosie w twojej funkcji C++ i jest niszczony zaraz po powrocie z niego. Powinieneś albo przekazać tablicę z C# i wypełnić ją w kodzie C++, albo przydzielić tablicę w stercie i dostarczyć jakiś środków do jej uwolnienia.

Po poprawnym użyciu obsługa będzie zależała od tego, w jaki sposób zwrócisz dane z kodu C++. Jeśli nadal jest to IntPtr, możesz użyć metod Marshal.ReadByte do odczytania znaków z pamięci i użyć metod kodowania, aby w razie potrzeby przekonwertować te bajty na łańcuch.

 

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

mam rozwiązanie następująco ::

NASZ kodu C++ wygląda następująco

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

i C# wygląda następująco

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

Jedyny problem teraz w obliczu tego, jak możemy poznać rozmiar tablicy , więc w tym zestawieniu string [] s = nowy ciąg [100]; Nie potrzebujemy marnować naszej pamięci.