2016-03-30 6 views
1

Ich googelte viel & nichts funktioniert in meinem Fall. Hier ist mein Code.Übergeben Zeichenfolge von C++ zu C# funktioniert nicht

CPP

char* pp = "this_is_text"; 
DLL_EXPORT void ToString_Internal(MicroObject* a_microObj, char* a_str) 
{ 
    *a_str = *pp; 
} 

#define DLL_EXPORT __declspec(dllexport)

C# (Import)

[DllImport("Serializer", CharSet = CharSet.Ansi)] 
private extern static void ToString_Internal(IntPtr a_ptr, StringBuilder a_builder); 

C# (usage)

StringBuilder l_builder = new StringBuilder(1000); //set 1000 len, for testing 
ToString_Internal (m_ptr, l_builder);  //invoke to DLL function 
Console.WriteLine (l_builder.ToString()); //print to console 

Questi auf # 1: Console.WriteLine() druckt nur den ersten Buchstaben ("t") im Terminal. Was ist das Problem?

Frage # 2: ich bin Speicher in C# (mit StringBuilder). Gibt C# GC in meinem Fall den Speicher frei oder muss ich den Speicher manuell freigeben und auf welcher Seite (C oder C#).

Wenn Sie Guyz brauchen mehr Informationen, lassen Sie es mich wissen.

+0

'* a_str = * pp;' - Sie verstehen, dass Kopien genau * ein * Zeichen, nicht wahr? – WhozCraig

+0

@DavidHeffernan Ah süß. Danke – MickyD

Antwort

3

Console.WriteLine() druckt nur Anfangsbuchstaben ("t") in Terminal. Was ist das Problem?

Sie nur ein Zeichen hier kopiert:

*a_str = *pp; 

Stattdessen Sie die gesamte Zeichenfolge kopieren müssen:

strcpy(a_str, pp); 

Natürlich fragen Sie einfach für einen Pufferüberlauf-Fehler mit diesem Code. Sie müssen auch die Länge des Puffers übergeben, wenn Sie die Funktion aufrufen, und veranlassen, dass Sie nicht über das Ende dieses Puffers hinaus kopieren.

Ich reserviere Speicher in C# (mit StringBuilder). Gibt C# GC in meinem Fall den Speicher frei oder muss ich den Speicher manuell freigeben und auf welcher Seite (C oder C#).

Speicher zum C++ Code weitergegeben wird durch die p/Invoke Rahmen verwaltet und es wird sichergestellt, dass es zugeordnet ist, und freigegeben korrekt. Sie müssen nichts mehr tun.


Aus dem Code, den Sie präsentieren, so scheint es, dass die Funktion der __cdecl Aufrufkonvention verwendet. In CallingConvention = CallingConvention.Cdecl zu Ihrem DllImport Attribute:

[DllImport("Serializer", CharSet = CharSet.Ansi, 
    CallingConvention = CallingConvention.Cdecl)] 
+0

Verstanden .. Thankx @David & andere. – MicroEyes