Frage

Ich habe die folgende Struktur in C ++:

#define MAXCHARS 15

typedef struct 
{
    char data[MAXCHARS];
    int prob[MAXCHARS];
} LPRData;

Und eine Funktion, die ich p bin / in Berufung auf eine Reihe von drei dieser Strukturen zu erhalten:

void GetData(LPRData *data);

In C ++ würde ich nur so etwas tun:

LPRData *Results;
Results = (LPRData *)malloc(MAXRESULTS*sizeof(LPRData));
GetData( Results );

Und es würde gut funktionieren, aber in C # kann ich nicht scheinen, damit es funktioniert. Ich habe einen C # struct wie folgt erstellt:

public struct LPRData
{

    /// char[15]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string data;

    /// int[15]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob;
}

Und wenn ich ein Array von 3 die initialisiert wird (und alle ihre Unterarrays) und gebe es in diesen:

GetData(LPRData[] data);

Es gibt mit Erfolg, aber die Daten in der LPRData Array hat sich nicht geändert.

Ich habe sogar versucht, einen rohen Byte-Array die Größe von 3 LPRData erstellen zu können und die in einen Funktionsprototyp wie folgt übergeben:

GetData (byte [] data);

Aber in diesem Fall werde ich die „Daten“ Zeichenfolge von der ersten LPRData Struktur, aber nichts, nachdem sie, einschließlich dem „prob“ Array aus dem gleichen LPRData erhalten.

Alle Ideen, wie diese richtig behandeln zu?

War es hilfreich?

Lösung

Ich würde versuchen, einige Attribute zu Ihrer Struktur decloration Hinzufügen

[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;

/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}

* Hinweis TotalBytesInStruct ist keine Variable darstellen soll

JaredPar ist auch richtig, dass die IntPtr-Klasse könnte hilfreich sein, aber es ist schon eine ganze Weile her, seit ich PInvoke verwendet haben, so rostig ich bin.

Andere Tipps

Ein Trick, wenn sie mit Zeigern zu tun ist, um nur einen IntPtr zu verwenden. Sie können dann Marshal.PtrToStructure auf den Zeiger und Erhöhung der Größe der Struktur basiert, um Ihre Ergebnisse zu erhalten.

static extern void GetData([Out] out IntPtr ptr);

LPRData[] GetData()
{
    IntPtr value;
    LPRData[] array = new LPRData[3];
    GetData(out value);
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = Marshal.PtrToStructure(value, typeof(LPRData));
        value += Marshal.SizeOf(typeof(LPRData));
    }
    return array;
}

Der PInvoke Interop-Assistent helfen kann. http://clrinterop.codeplex.com/releases/view/14120

Haben Sie markieren GetData Parameter mit OutAttribute ?

  

die InAttribute Kombinieren und   OutAttribute ist besonders nützlich,   bei Anwendung auf Arrays und formatiert,   Nicht-blitfähig Typen. Anrufer sehen die   ändert sich ein Angerufener auf diese Art macht   nur, wenn Sie beide Attribute gelten.

Ein ähnliches Thema wurde auf diese Frage , und der von die Schlussfolgerungen waren, dass die CharSet benannten Parameter auf CharSet.Ansi eingestellt werden müssen. Andernfalls würden wir eine wchar_t Array werden zu machen, anstatt eine char Array. Somit wäre der richtige Code wie folgt:

[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LPRData
{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
    public string data;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
    public int[] prob;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top