Laden...

[erledigt] Marshalling Problem: SafeArray und VARIANT

Letzter Beitrag vor 16 Jahren 3 Posts 1.488 Views
[erledigt] Marshalling Problem: SafeArray und VARIANT

Moin zusammen,

folgende Problemstellung. Ein in meiner Anwendung verwendetes ActiveX-Control stellt die Methode

 sendRCP(object rCP)

zur Verfügung. Laut Doku des Hertellers erwartet die Methode einen...

...Variant of type SafeArray that holds the command to be transmitted. For the definition of variants and SafeArrays see the Microsoft OLE documentation.

Die Daten die ich übergebe haben folgendes Layout:

struct RcppMessage {
   public short command;
   public byte dataType;
   public byte versionReadWrite;
   public byte action;
   public byte reserved;
   public short clientId;
   public long sessionId;
   public short num;
   public short payloadLength;
   public byte[] payload;
}

Seit ich heute morgen an meinem Arbeitsplatz sitze, reise ich durch die unendlichen Weiten des großen **:::

Erster Ansatz war der folgende:

[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
private RcppMessage[] m_rcppCommands;

private void sendCommand () {
   
   msg = new RcppMessage();

   msg.versionReadWrite = 0x31;
   msg.action = 0x00;
   msg.reserved = 0x00;
   msg.clientId = ClientID;
   msg.sessionId = 0;
   msg.command = 0x0019;
   msg.dataType = 0x14;
   msg.num = 0;
   msg.payloadLength = 0;
   msg.payload = new byte[0];

   m_rcppCommands= new RcppMessage[] { msg };

   return ocxDisplay.SendRCP( m_rcppCommands);
}

Das liefert bei Aufruf der Methode ocxDisplay.SendRCP eine Exception mit folgendem Inhalt:

Falscher Parameter. (Ausnahme von HRESULT: 0x80070057 (E_INVALIDARG))

Der zweite Ansatz war das Struct RcppMessage direkt als SafeArray zu "marshaln" - das hat aber auch nicht funktioniert.

Hat jemand von Euch Erfahrung mit sowas und kann mir helfen dieser Methode das Struct so zu übergeben, dass sie keine Exception mehr schmeißt?

Gruß,
Markus 🙂

Hallo Spontifixus,

versuch mal folgendes:


private void sendCommand () {

   msg = new RcppMessage();

   msg.versionReadWrite = 0x31;
   msg.action = 0x00;
   msg.reserved = 0x00;
   msg.clientId = ClientID;
   msg.sessionId = 0;
   msg.command = 0x0019;
   msg.dataType = 0x14;
   msg.num = 0;
   msg.payloadLength = 0;
   msg.payload = new byte[0];

   return ocxDisplay.SendRCP(new object[]{ msg});
}


Bei VARIANT ist halt immer blöd ohne dne zugrundeliegend C++ Code nachzusehen wie das SafeArray schlussendlich ausgelesen wird. Eine Kapselung wie m_rcppCommands= new RcppMessage[] { msg }; kommt mir aber spanisch vor, oder hatte der Hersteller das expleziet verlangt?

Wenn das nicht hinhaut denke ich eher das folgende snoch gemeint sein könnte:


private void sendCommand () {

   msg = new RcppMessage();

   msg.versionReadWrite = 0x31;
   msg.action = 0x00;
   msg.reserved = 0x00;
   msg.clientId = ClientID;
   msg.sessionId = 0;
   msg.command = 0x0019;
   msg.dataType = 0x14;
   msg.num = 0;
   msg.payloadLength = 0;
   msg.payload = new byte[0];

   return ocxDisplay.SendRCP(new object[]{ msg.versionReadWrite, msg.action, msg.reserved, msg.clientId,  msg.sessionId, msg.command, msg.dataType, msg.num, msg.payloadLength, msg.payload });
}


Ich hatte Variant mal für nen BITMAP ohne Headerdateien.. das sah dann so aus 😉


    public static object ConvertToVariantBitmap(Image img)
    {
      byte[] array = null;
      using (MemoryStream stream = new MemoryStream())
      {
        img.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
        stream.Position = 14; // rewind to non header information
        array = new byte[stream.Length - 14]; // remove bm header informations
        stream.Read(array, 0, (int)stream.Length - 14); // read non header informations
      }

      return array;
    }

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

Hallo Andreas,

vielen Dank für deine Hilfe - die Variante mit den Werten in einem object[] hat's gebracht. Jetzt macht die Methode zwar immer noch nicht was sie soll aber sie schmeißt keine Exception mehr... - und das sie nicht das mach, was sie soll liegt an den übergebenen Werten.

Nochmals danke!

Gruß,
Markus 🙂