2015-05-04 2 views
15

Ich versuche eine normale C-Funktion von einer externen DLL aus meiner C# -Anwendung aufzurufen. Diese Funktion wird alsWie übermittele ich ein const Char * von C# zu einer C-Funktion?

definiert
void set_param(const char *data) 

Jetzt habe ich einige Probleme mit dieser Funktion:

  1. Wie gebe ich diese "const" in C# -Code? public static extern void set_param(sbyte *data) scheint den "const" Teil zu verpassen.

  2. Wie übertrage ich beim Aufruf dieser Funktion eine einfache 8-Bit C-Saite? Ein Anruf an set_param("127.0.0.1") führt zu einer Fehlermeldung, "kann nicht von 'string' zu 'sbyte'" * konvertieren.

+0

Ich denke 'public static extern void set_param (string data)' sollte funktionieren. –

+1

Ich denke, Sie finden viele Beispiele finden Sie hier http://pinvoke.net/ – kenny

Antwort

25

Es sieht aus wie Sie den ANSI-Zeichensatz verwenden, so dass Sie die P erklären könnte/Invoke etwa so:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi)] 
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString); 

.NET Einweiser behandelt Kopien von Strings zu machen und zum Umwandeln der Daten zum richtigen Typ für dich.

Wenn Sie einen Fehler mit einem unausgeglichenen Stack haben, müssen Sie die Aufrufkonvention stellen Sie Ihr C-DLL entsprechen, zum Beispiel:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 

Siehe pinvoke.net für viele Beispiele Windows-API-Funktionen.

Siehe auch Microsoft's documentation on pinvoking strings.

+0

Dies verursacht eine Ausnahme: Ein Aufruf der PInvoke-Funktion 'yourdll.dll :: set_param' hat den Stapel aus dem Gleichgewicht gebracht. Dies liegt wahrscheinlich daran, dass die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur übereinstimmt. – Elmi

+0

@Elmi Sie müssen also die Aufrufkonvention der C-DLL kennen, damit Sie sie in P/Invoke angeben können. Welche Aufrufkonvention verwendet es? –

+0

Matthew Watson: Die DLL hat einfache undekorierte C-Funktionen, alle ANSI-C, __declspec (dllexport) – Elmi

4

Ein const char* ist einfach ein string in .NET - die verwaltete Seite versteht (noch) nicht den Begriff der schreibgeschützten Parameter. Wenn Sie dies in einem P/Invoke-Kontext verwenden, sollten Sie ein MarshalAs-Attribut deklarieren und es als LPStr marshalieren. Die sich ergebende Signatur aussehen würde, etwas entlang der Linien von

[DllImport("SomeModule.dll")] 
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString); 

Es gibt auch dieses article on MSDN mit mehr Informationen darüber, wie zu einer verwalteten Umgebung nativen Strings Marschall.

+0

Ist keine Zeichenfolge in .NET Unicode? Wie würde es auch bei der UTF-8-Codierung für ASCII 128-255 (Gebietsschema-spezifisch usw.) zuverlässig funktionieren? –

+1

@PeterMortensen Für ASCII 128-255 würden Sie 'LPWStr' verwenden, das eine 2-Byte-Zeichenkette darstellt. Ab .NET 4.7 wurde "LPUTF8Str" zu "nativ" UTF8-Strings hinzugefügt, anstatt ein "IntPtr" zurückzugeben und sie auch manuell zu bearbeiten. Nebenbei bemerkt, Streicher in.NET sind UTF-16, das ist, was Microsoft als Unicode bezeichnet, aber ist eine andere Variante von Unicode-Iirc, aber Sie würden mit Recht sagen, dass Zeichenfolgen in .NET Unicode sind. – aevitas

Verwandte Themen