DllImport-und char-Marshalling
Ich bin Neuling in C# und Marshalling. Ich muss an meinem C func in C#, aber ich habe einen falschen Rückgabewert von C func (oder ich weiß nicht, wie es zu konvertieren, um die richtige Antwort).
C Quelle:
#include "main.h"
char *Ololo(char *arg, int &n3)
{
char *szRet;
szRet=(char*)malloc(strlen(arg)+1);
strcpy(szRet,arg);
n3 = strlen(szRet);
return szRet;
}
C-header:
extern "C" __declspec(dllexport) char *Ololo(char *arg, int &n3);
C# - Quelle:
class Program
{
[DllImport(@"F:\Projects\service\dll\testDLL2.DLL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern IntPtr Ololo([In] char[] arg, ref Int32 n3);
static void Main(string[] args)
{
string n1 = "ololo";
char[] chars = new char[n1.Length];
chars = n1.ToCharArray();
Int32 n3 = 0;
IntPtr result;
result = Ololo(chars, ref n3);
string n4 = Marshal.PtrToStringUni(result,n3);
Console.WriteLine(n4);
}
}
Habe ich etwas von dem zurückgeben, wie "o?? ?"
Sorry für schlechtes Englisch
----------------------Gelöst-----------------------
class Program
{
[DllImport(@"F:\Projects\service\dll\testDLL2.DLL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern IntPtr Ololo([MarshalAs(UnmanagedType.LPStr)]string arg, ref Int32 n3);
static void Main(string[] args)
{
string n1 = "ololo";
Int32 n3 = 0;
int n2 = n1.Length;
IntPtr result;
result = Ololo(n1, ref n3);
string n4 = Marshal.PtrToStringAnsi(result, n3);
Console.WriteLine(n4);
}
}
Das funktioniert auch. In n3 habe ich 5 und n4 ololo! Danke für s schnelle Antworten!
btw 'int &n3' ist nicht C, der C++ - notation.
Sie haben nichts gelöst, der code verliert den Speicher für den string.
mögliche Duplikate von Char * marshalling in C#
Passant einen Unterschied gibt Es allerdings: Auf dem link func zurück char * war rewrited void func. In meiner Frage, der erste war wie zu fangen return(char ). Und wenn es einen memory-leak, wie die Kostenlose Rücksendung(char) in c#?
Sie haben nichts gelöst, der code verliert den Speicher für den string.
mögliche Duplikate von Char * marshalling in C#
Passant einen Unterschied gibt Es allerdings: Auf dem link func zurück char * war rewrited void func. In meiner Frage, der erste war wie zu fangen return(char ). Und wenn es einen memory-leak, wie die Kostenlose Rücksendung(char) in c#?
InformationsquelleAutor Treno1 | 2012-09-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
public static extern IntPtr Ololo([In] char[] arg, ref Int32 n3);
IntPtr
ist der falsche zurück geben, da im wesentlichen Sie wollen auf den string, nicht einen Zeiger auf die Zeichenfolge. In C können Sie einen Zeiger auf die Zeichenfolge mithilfechar*
, das entspricht in .Wäre NET verwenden, verwenden Sie diese:[MarshalAs(UnmanagedType.LPStr)]string
. Dies sollte marshallchar*
zu einemstring
richtig.IntPtr
repräsentiert einen Zeiger geben, die, um Ihre eigentliche string ist nutzlos.Sieht auch, wie Sie sein sollte unter ein
StringBuilder
in Ihrer Funktion Gemarshallt, und nicht einchar[]
. Dann zumindest sollten Sie immer die richtige Zeichenfolge, um Ihre C-Funktion.IntPtr
ist korrekt, dan3
gibt mir 1 und intIntPtr
ichve got first letter (o). But why I have
n3` = 1? Ich denke, es musss to be 5. Because of that I think
[In] char[] arg` ist falsch. Aber was ist nun richtig?Siehe meine Antwort bearbeitet
Ihre Funktion in .NET wird nie geben Sie die gesamte Zeichenfolge zurück, wenn Sie zurück
IntPtr
.System.AccessViolationException wenn ich versuche zu
public static extern StringBuilder Ololo(string arg, ref Int32 n3);
undStringBuilder n5 = Ololo(n1, ref n3);
Danke! Gelöst! Up!
InformationsquelleAutor Tony The Lion
Den marshaller nicht NULL beenden
char
arrays für funsies. Wird Sie es tun, weil du es gesagt hast- wenn du es gesagt hast. Sie sind glücklich, weil einchar
.NET ist UTF-16, und das ist 16 bit breit und das zweite byte gleich null sein wird, denn das ist'o'
im UTF-16, so dass ein strlen 1. Der tatsächliche Aufwand für eine verwaltete Zeichenfolge als eine null-terminierte C-saite ist ein bisschen höher als die, die Sie zu schätzen scheinen. So lassen Sie die marshaller alle Arbeit tun - es weiß bereits, wie diese Arbeit zu tun.public static extern [MarshalAs(UnmanagedType.LPStr)]string Ololo
ist falsch, weil der[MarshalAs(UnmanagedType.LPStr)] cannot be in declaration of class , structure or interface
.Das ist es nicht. Sie müssen nicht zu kopieren das DLLImport-Attribut, über platziert, oder die Erklärung in der falschen Stelle.
Danke! Gelöst! Up!
InformationsquelleAutor Puppy