Frage

Ich habe eine wirklich harte Zeit, diese Rangierung nach unten.

Ich habe umanaged Code, der wie folgt aussieht:

WORD HLP_GetDeviceNames (LPSTR *DevNames, WORD Max_Len, WORD Max_Num)

Just FYI habe ich nicht diesen nicht verwalteten Code schreiben, aber es verwenden müssen.

Returns:. WORD einen Fehler anzeigt

DEVNAMES: Zeiger auf ein Array von char Arrays. Im Grunde ein Array von Strings, die geändert werden und kehrte zu mir zurück!

MAX_LEN: Länge der einzelnen Strings (ich höre dies sein muss, 256)

MAX_NUM: Die Länge des Arrays. Ich verwende einen anderen Invoke-Aufruf, der das sagt mir Anzahl der Geräte arbeitet so, ich weiß genau, wie viele Strings zu senden.

Ich habe eine Menge von diesem aus P / Invoke Interop signatureToolkit zu Figur verwendet, aber lesen Sie auch ein Bündel noch weiter zu erhalten. Wo bin ich jetzt hier:

[DllImport("UsbMeasLib.dll")]
public static extern ushort HLP_GetDeviceNames([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] ref StringBuilder[] DevNames, ushort Max_Len, ushort Max_Num);

Ich nenne meinen Code wie folgt:

StringBuilder[] DevNames = new StringBuilder[deviceCount];
     for(int i = 0; i< deviceCount; i++)
     {
           DevNames[i] = new StringBuilder().Append(' ', 256);
     }

     HachUsbMeasLib.HLP_GetDeviceNames(ref DevNames, 256, Convert.ToUInt16(DevNames.Count())); 

Ich bin mit String-Builder-Array, weil ich den nicht verwalteten Code benötigen, um die String-Builder zu modifizieren, dass sie die neue Zeichenfolge zurückgeben können, da String unmutable ist.

Wenn ich den Code ausführen, My Array ist nicht modifiziert!

Ich bin nicht wirklich sicher, was los ist, aber ich denke, es hat etwas mit CLR sagen, nicht verwalteten Code zu tun, um nicht meine Array anstelle zu ändern, sondern schafft stattdessen eine neue Referenz (Zeiger). Selbst wenn dies der Fall ist, ich weiß nicht, wie es zu beheben.

Vielen Dank für jede Einsicht jemand bieten kann!

War es hilfreich?

Lösung 2

dachte ich diese heraus. Dank jedem, der antwortete.

Ich fand heraus, wie es funktioniert. Ich habe einfach den Speicherplatz liefern, aber ich muß das Marshalling wissen lassen, dass ich erwarte, dass in und mit diesem Objekt, damit es den nicht verwalteten Code ermöglicht den zugewiesenen Speicherplatz zu ändern.

Ich habe es wie folgt aus:

[DllImport("UsbMeasLib.dll")]
private static extern ushort HLP_GetDeviceNames([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] DevNames, ushort Max_Len, ushort Max_Num);

verwende ich Zeichenfolge anstelle von String-Builder, weil der nicht verwalteten Code wird einfach die Zeichenfolge ersetzen, die in Ordnung ist. Ich erhalte die Array-Zeiger zurück, nicht modifizierten Zeichenfolgen. der verwalteten Code ist nur ein Array von Zeigern auf Punkt zu neuen String-Objekten zu ändern (glaube ich).

int numDev = HLP_GetNumDevices();


string[] names = new string[numDev];

for (int i = 0; i < names.Length; i++)
{
    names[i] = new StringBuilder().Append(' ', 256).ToString();
}

ushort errorCode = HLP_GetDeviceNames(names, 256, Convert.ToUInt16(numDev));

I weisen Speicher für den unamanged Code dann lassen Sie den nicht verwalteten Code chane dort die Saiten.

Das funktioniert aber ich weiß nicht, ob ich irgendwelche potenzielle Speicherlecks oder andere potenzielle Probleme haben.

Andere Tipps

Versuchen Sie, auf niedrigem Niveau zu arbeiten. Declare DEVNAMES Parameter als IntPtr []. Bereiten Sie es durch die folgende Weise:

IntPtr[] devNames = new IntPtr[deviceCount];

for(int i = 0; i < deviceCount; i++) 
{ 
    devNames[i] = Marshal.AllocHGlobal[256];
}

Geben Sie diese Array HLP_GetDeviceNames. Zur Ausgabe von Daten zu verarbeiten, gelten Marshal.PtrToStringAnsi jedes DEVNAMES Mitglied. Vergessen Sie nicht lösen DEVNAMES [i] mit Marshal.FreeHGlobal am Ende.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top