Autor Beitrag
meisse
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Mi 06.07.11 17:58 
Hallo zusammen

Folgendes ist gegeben: Aus dem C# Code wird eine Methode aus einer C++ DLL aufgerufen, um Daten anzufordern. Mit den Attributen der Methode definiere ich welche Daten ich gerne haben möchte. Zusätzlich gebe ich ein callback delegate mit. In der C++ DLL werden dann die Daten aufbereitet und in ein array abgespeichert, welches folgendermassen deklariert ist:
ausblenden C#-Quelltext
1:
uint8_t* m_dataBlock = new uint8_t[1024];					

Das callback delegate sieht folgendermassen aus:
ausblenden C#-Quelltext
1:
typedef void (TPC_CC *TPC_DataStreamCallback)(void *DataPtr, int DataLength);					

Wenn das Datenarray 'm_dataBlock' gefüllt wurde, wird die callback methode aufgerufen:
ausblenden C#-Quelltext
1:
2:
3:
if(m_StreamBufferSize > 0) {
        m_callback(m_dataPtr, 1024);
      }


In meiner C# Applikation wird danach die callback methode aufgerufen, mit welcher ich dann gerne auf das Array zugreifen möchte:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
public static void DispatchRawDataStream(IntPtr DataPtr, int DataLength) {
            Int32[] data = new Int32[DataLength];
            GCHandle gcHandleData = GCHandle.FromIntPtr(DataPtr);
            data = (Int32[])gcHandleData.Target;

            lock (StreamQueueObj.lockObj) {
                StreamQueueObj.DataChunk.Enqueue(data);
            }
        }


Nur mit dieser Variante bekomme ich folgende Exception: ArgumentException überschreitet eine systemeigene/verwaltete Grenze. GCHandle kann nicht zwischen AppDomains übergeben werden.

Kann mir da jemand weiterhelfen?

Mit freundlichen Grüssen
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 06.07.11 19:59 
Ich vermute das C++ Array liegt auf dem unmanaged Heap und ist damit für C# nicht direkt erreichbar. Du musst den Speicherinhalt des Array erst auf den managed Heap kopieren um ihn verwenden zu können. Da hilft z.B. eine der Marshal.Copy Überladungen.

Ist uint8_t nicht einfach ein Byte? Wie passt das zu Int32? Wäre da auf .Net Seite nicht auch ein Byte Array sinnvoller?

Für diesen Beitrag haben gedankt: meisse
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Do 07.07.11 00:02 
Ok danke, werde ich morgen gleich ausprobieren.

Ja das stimmt. uint8_t ist ein unsigned char. Da hab ich was falsch verstanden. Werde mich wieder melden sobald alles funktioniert.

Mit freundlichen Grüssen
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Do 07.07.11 08:34 
Das ganze hat funktioniert mit dem Marshal.Copy Befehl:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
public static void DispatchRawDataStream(IntPtr DataPtr, int DataLength) {
            byte[] data = new byte[DataLength];
            Marshal.Copy(DataPtr, data, 0, DataLength);

            lock (StreamQueueObj.lockObj) {
                //StreamQueueObj.DataChunk.Enqueue(data);
            }
        }


Jetzt muss ich nur noch die Daten richtig interpretieren.

Mit freundlichen Grüssen