# Com4j Variant Problem



## re_steber (5. Februar 2008)

Hallo zusammen

Dieser Forumbeitrag ist für mich eine Premiere. Ich hoffe er ist am richtigen Ort plaziert...

Problemstellungen:
Über Com4j steure ich ein COM Objekt an. Das Com Objet dient zum Steuern der Software PLCSIM von Siemens. Das Erstellen der Wrapperkassen mit com4j funktionierte ohne Problem und ich konnte auch schon Verbindung aufbauen (was so viel heisst wie, dass es mir möglich war über einfache Schnittstellenmethoden ohne Rückgabewerte die Software fernzusteuern). Es gibt aber auch einige Schnittstellenmethoden welche als Rückgabewert einen Java Object haben. In diesem Object befinden sich ein Array von Bytes auf welches ich gerne auslesen möchte.
Auszug aus dem von com4j generierten Interface:

    /**
     * Reads single bit, byte, word, or double word from a Control Engine Data Block.
     */
    @VTID(30)
    void readDataBlockValue(
        int blockNum,
        int byteIndex,
        int bitIndex,
        plcsim.com.PointDataTypeConstants dataType,
        java.lang.Object pData);


 Laut der Schnittstellendefinition (im Anhang) ist dieses Java Object ein Variant.

Wie muss ich vorgehen um diese Variant auszulesen ?

Besten Dank für eure Hilfe.


----------



## CiNcH (8. März 2008)

Ich komme da auch nicht weiter. Habe auch eine Methode mit einem Parameter OleVariant SafeArray und komm da nicht an die Daten. Ich gebe in die Methode ein leeres Variant-Objekt und wenn die Methode zurückkehrt ist dieses Variant-Object nun immerhin vom "Typ" VT_ARRAY_VARIANT.

Hast du mittlerweile schon eine Lösung gefunden?


----------



## re_steber (10. März 2008)

Hallo...
Ich habe ein Lösung für das Probelm gefunden... jedoch nicht mit com4j sondern mit jacob http://danadler.com/jacob/. Diese Java2Com Bridge funktioniert super... Leider kann ich hier nicht den Code publizieren, da dieser nicht mein Eigentum ist, jedoch solltes du alle nötigen Infomationen auf der Jacob Seite finden um dein Problem zu lösen. Kleiner Tipp, es muss nicht zwingend eine Wrapperklasse generiert werden. Es reicht, wenn du das jacob Jar und das C Gegenstück in dein Programm implementierts. Anschliessen kanns du mit grundlegenden Befehlen, Methoden deines COM Objekts ansteuern.
Gruss


----------



## CiNcH (10. März 2008)

Hmmm, ja, das ist meine letzte Ausflucht. Aber läuft da nicht irgendwie alles über Reflection? Ich fand COM4J so super weil es die definitions generiert und man dann gegen diese Indirektionen programmieren kann (schöner objektorientierter Code, und man kann "IntelliSense" verwenden).

Danke jedenfalls für den Tipp.


----------



## re_steber (13. März 2008)

Hallo...
Ehrlich gesagt habe ich mich mit der Reflection API noch garn nicht beschäftig... (ich haben leider noch wenig Erfahrung mit Java)

Um dir jedoch zu zeigen wie einfach das ganze mit Jacob ist habe ich dir ein wenig Code zusammenkopiert (Dieses Beispiel ist ohne generierten Wrapper realisiert).


```
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.SafeArray;
import com.jacob.com.Variant;

public class VClientStub
{
  
  private ActiveXComponent comObject;

  public void initAccess() throws Exception
  {
    
    //Stellt Verbindung mit comObject COM Object her
    comObject = new ActiveXComponent("Name des Com Object");
    
    
    //Erstellen des Variant, in welches die Rückgabewerte geschrieben werden
    Variant paramOutputImage = new Variant();
    Byte fillbyte = 0;
    paramOutputImage.putVariant(fillbyte);
    
    //Aufbereiten der Übergabeparameter für den Aufruf der comObject Funktion
    Variant[] args = new Variant[] { new Variant(0), new Variant(2),new Variant(2), paramOutputImage};   
    comObject.invoke("ReadOutputImage", args);
    
    //Rückgabewert in SafeArray casten
    SafeArray tempSaveArray = (SafeArray)args[3].getVariant();   
    
    //Auslesen des SafeArray   
    for (int i = 0; i < result.length; i++)
    {
      result[i] = tempSaveArray.getByte(i);
    }
    
  }

}
```

Dieses Beispiel bezieht sich auf eine Methode eines COM Objekts, welche wie folgt aussieht:

ReadOutputImage( long StartIndex, long ElementsToRead, ImageDataTypeConstants DataType, VARIANT* pData)

Wobei der letze Parameter das SafeArray beinhaltet....

Um dieses Beispiel auf ein anderes Probelm zu übertragen:
- "Name" des Com Objects anpassen 
- Zusammenstellung der Argumente und Methodennamen anpassen

Alle Informationen über das anzusteuernde Com Objet (Namen + Methodennamen) erhälts du mit dem OLE/COM Viewer von Microsoft


----------



## IggeB (17. März 2010)

Hallo.
Ich benutze auch die Java-COM Brücke Jacob um aus einer Datenbank Messdaten auszulesen.
Der Verbindungsaufbau klappt gut, allerdings habe ich noch Probleme beim Auslesen der Daten.
Mit der Methode ReadTags()  der zugehörigen DLL möchte ich die Daten auf ein Variant-Objekt speichern:

Variant vResultValue = Dispatch.call( FuelWorkAuto, "ReadTags" );

Allerdings weiß ich nicht genau wie ich über das Objekt jetzt an die Daten herankomme. Die Messdaten müssten in einem mehrdimensionalen Array gespeichert sein. 
Habe im Internet recherchiert und bin dabei auf SafeArrays gestoßen. Allerdings bin ich damit auch nicht weitergekommen.
Kann mir vllt jemand weiterhelfen?

Gruß


----------

