Wie kann ich passieren Memory Daten auf nicht verwalteten C ++ DLL unter Verwendung von P / Invoke

StackOverflow https://stackoverflow.com/questions/1054009

Frage

Ich brauche Ihre Hilfe mit dem folgende Szenario:

Ich lese einige Daten von der Hardware in einen Memorystream (C #) und ich brauche diese Daten im Speicher in einer DLL in nicht verwalteten C implementiert passieren ++ (mit Zeigern ??). Die gelesenen Daten (in Strom) sehr groß (Megabyte). Ich verstehe, dass ich P / diese dll aufrufen, aber was ich bin nicht sicher, wie der Zeiger / Referenz der Stream-Daten an die C ++ API zu übergeben?

Ich muss zugeben, ich bin verwirrt, wie ich C # bin hier - muss ich da die Daten unsicher / Fest verwenden groß ist oder diese sind irrelevant, da Objekt Memory von GC verwaltet wird? Einige Beispiel-Code / ausführliche Beschreibung wäre sehr hilfreich. Dank

Signatur von nicht verwalteten API:

BOOL doSomething (void * rawData, int dataLength)

War es hilfreich?

Lösung

Wenn es nur Bytes erwartet Sie das Memorystream in eine Byte-Array lesen und dann einen Zeiger auf das an die Methode übergeben.

Sie müssen die externe Methode deklarieren:

[DllImport("mylibrary.dll", CharSet = CharSet.Auto)]
public static extern bool doSomething(IntPtr rawData, int dataLength);

Dann lesen Sie den Bytes aus dem Memorystream in einen Byte-Array. Vergeben Sie einen GCHandle welche:

  

Sobald zugewiesen, können Sie eine GCHandle verwenden   das verwaltete Objekt zu verhindern,   durch den Müll gesammelt   Sammler, wenn ein nicht verwalteten Client   hält die einzige Referenz. ohne eine solche   ein Griff, kann das Objekt gesammelt werden   vom Garbage Collector vor   Abschluss seiner Arbeit im Namen der   nicht verwalteten Client.

Und schließlich verwenden die AddrOfPinnedObject Methode ein IntPtr zu bekommen, um die C ++ DLL zu übergeben.

private void CallTheMethod(MemoryStream memStream)
{
   byte[] rawData = new byte[memStream.Length];
   memStream.Read(rawData, 0, memStream.Length);

   GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
   IntPtr address = handle.AddrOfPinnedObject ();

   doSomething(address, rawData.Length);
   rawDataHandle.Free();
 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top