2012-04-04 10 views
2

nicht beibehalten Ich habe einen C# -Code, der eine C++ - Funktion aufruft.Array-Änderung in C++ - Funktion wird in C#

Die C++ - Funktion sollte einen Puffer füllen, der mit einem Zeiger übergeben wird. Das Array gibt jedoch leer zurück.

Die Einfuhranmeldung ist:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)] 
public static extern UInt32 FillArr(char[] arr); 

Der Code nach Vereinfachungen und sieht so, dass einige hart codierte Werte eingeben:

Der Code in C#:

char[] arr= new char[10]; 
ret = LogicInterface.FillArr(arr); 

Der C++ Code :

bool FillArr(char* arr) 
{ 
     int length=10; 
     for(int i = 0; i < length; i++) 
     { 
       arr[i] = 3; //replaced with some hard coded value 
     } 
     return true; 
} 

Das Array bleibt jedoch leer.

Irgendwelche Vorschläge?

Antwort

1

Ich glaube, dass Sie das Array vor der Übergabe an den systemeigenen Code pinnen müssten. Dies verhindert, dass der GC das verwaltete Array im Speicher verschiebt, während Sie in C++ darauf zugreifen.

So könnten Sie verwenden:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)] 
public static extern UInt32 FillArr(char* arr); 

Und dann:

char[] arr = new char[ 10 ]; 

fixed (char* pinned = arr) 
{ 
    ret = LogicInterface.FillArr(pinned); 
} 

Hinweis, dass ich nicht wirklich kompiliert und ausgeführt, aber es sollte Ihnen einige Ideen geben, wie zu verfahren.

1

Sie müssen das Array nicht anheften, solange der Code in C++ es nicht vor der Rückgabe zwischenspeichert.

In Ihrem Fall müssen Sie das Array als Referenz übergeben, damit es als ein out-Argument betrachtet werden kann.

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)] 
public static extern UInt32 FillArr(ref char[] arr);` 
+0

Würden die Einweiser dann unter der Haube den Speicherstift? – Nick

+0

Ja. siehe hier: http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2 – Pedro

-1

Gefunden diesen Link sehr nützlich:

C#: calling C++ DLL with char** argument

Der letzte Code wie folgt aussieht:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)] 
    static extern bool FillArr([MarshalAs(UnmanagedType.LPStr, ArraySubType = UnmanagedType.LPStr)] StringBuilder args); 

     static void Main(string[] args) 
     { 
      StringBuilder arr = new StringBuilder(9); 
      bool res = FillArr(arr); 
     } 
+0

Ah, Sie sind Strings Marshalsing ... nicht nur Arrays von char wie in der ursprünglichen Frage beschrieben. – Nick

+0

@Nick Ich würde lieber Char-Array verwenden, aber es hat nicht funktioniert. Noch deine Antwort und die andere. Auf diese Weise kann ich es wieder als String analysieren und es als Char-Array verwenden. – sara