/
rc.com.native

rc.com.native

Methoden von COM-Objekten werden normalerweise als Methoden von JS-Objekten aufgerufen. Dabei analysiert die Scriptengine die COM-Methoden-Parameter (durch TypeInfo) und die übergebenen JS-Variablen und nimmt die notwendige Konvertierungen vor.
Manchmal ist allerdings mehr Kontrolle notwendig (z. B. beim Debuggen).

Zu diesem Zweck findet das rc.com.native Objekt seine Verwendung. Es beinhaltet:

  • Konstruktor Variant

  • Konstruktor SafeArray

  • Methode invoke

  • Methode __dump

  • Methode __ptr

  • Konstanten VARENUM

  • Konstanten INVOKE_FLAGS

rc.com.native.Variant

Code

const v = new rc.com.native.Variant(value,type);
  • Es wird ein VARIANT mit gegebenem VT_xx(type) und valueerstellt.

  • VT_BYREF ist ebenfalls erlaubt, in diesem Fall muss value ein rc.com.native.Variant sein.

  • Aus value wird der VARIANT Inhalt konstruiert, s. Kapitel "Conversion"

  • Der Inhalt von rc.com.native.Variant kann nachträglich nicht mehr geändert werden. Wenn es allerdings ein Ziel für VT_BYREF ist, kann die aufgerufene COM-Methode den Inhalt ändern.

  • rc.com.native.Variant kann als Parameter bei COM-Methoden verwendet werden.

  • rc.com.native.Variant hat die Eigenschaft $type und die Methoden getVartypetoJS,  __dbgOutput und __binOutput.

    • Methode getVartype(): gibt VT_xx Typ aus.

    • Methode toJS() : konvertiert rc.com.native.Variant in eine JS-Variable.

    • Um zu prüfen welchen Inhalt des Variants oxv8 konstruiert hat, gibt es folgende Methoden:

      • __dbgOutput :  erstellt Zusammenfassung vom VARIANT in einer lesbaren Form

      • __binOutput : gibt binären Inhalt vom VARIANT aus

Diese Code-Fragmente illustrieren die obigen Ausführungen. Nachfolgend gibt der Output des Codebeispiels die Wirkungsweise an:

Code

const obj = new rc.com.ActiveXObject("oxv8.Test_Echo_Single_InOut"); const vParam1 = new rc.com.native.Variant(33,vt.VT_I4); const vParam2 = new rc.com.native.Variant(44,vt.VT_I4); print(0,"Before call"); printVariant(1,"vParam1",vParam1); printVariant(1,"vParam2",vParam2); invokeMethod(1,obj,"F_int",[newByref(vParam1),newByref(vParam2)]); print(0,"After call"); printVariant(1,"vParam1",vParam1); printVariant(1,"vParam2",vParam2);
Before call    vParam1 [0x0000000002598FF0]: 123456       DbgOut: {"vt":20,"VT":"VT_I8","value":"123456","altValues":["0x000000000001E240"]}       BinOut: 14 00-00 00 00 00 00 00-40 E2 01 00 00 00 00 00-00 00 00 00 00 00 00 00    Before invoke       Param #0 [0x0000000002598FF0]: 123456          DbgOut: {"vt":20,"VT":"VT_I8","value":"123456","altValues":["0x000000000001E240"]}          BinOut: 14 00-00 00 00 00 00 00-40 E2 01 00 00 00 00 00-00 00 00 00 00 00 00 00       Result [0x000000000259A800]: undefined          DbgOut: {"vt":0,"VT":"VT_EMPTY"}          BinOut: 00 00-00 00 00 00 00 00-00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00    After invoke       Param #0 [0x0000000002598FF0]: 123456          DbgOut: {"vt":20,"VT":"VT_I8","value":"123456","altValues":["0x000000000001E240"]}          BinOut: 14 00-00 00 00 00 00 00-40 E2 01 00 00 00 00 00-00 00 00 00 00 00 00 00       Result [0x000000000259A800]: 123456          DbgOut: {"vt":3,"VT":"VT_I4","value":"123456","altValues":["0x0001E240"]}          BinOut: 03 00-00 00 00 00 00 00-40 E2 01 00 00 00 00 00-00 00 00 00 00 00 00 00 After call    vParam1 [0x0000000002598FF0]: 123456       DbgOut: {"vt":20,"VT":"VT_I8","value":"123456","altValues":["0x000000000001E240"]}       BinOut: 14 00-00 00 00 00 00 00-40 E2 01 00 00 00 00 00-00 00 00 00 00 00 00 00    result [0x000000000259A800]: 123456       DbgOut: {"vt":3,"VT":"VT_I4","value":"123456","altValues":["0x0001E240"]}       BinOut: 03 00-00 00 00 00 00 00-40 E2 01 00 00 00 00 00-00 00 00 00 00 00 00 00

rc.com.native.SafeArray

Es wird ein SAFEARRAY mit bestimmten VT_xx Typ und Bounds erstellt, bei Bedarf mit mehr als einer Dimension.

Folgende Konstruktoren stehen zur Verfügung:

Code

const a = new rc.com.native.SafeArray(value); // erstellt ein Array mit Dim=1, value wird nach SAFEARRAY konvertiert, s. conversion/arrays const a = new rc.com.native.SafeArray(type,bounds); // erstellt ein Array mit bestimmten Bounds const a = new rc.com.native.SafeArray(type,bounds,values); // erstellt ein Array mit bestimmten Bounds und Values

type ist ein VT_xx Typ (ohne VT_ARRAY), VT_BYREF ist nicht erlaubt.

Mögliche Werte für bounds sind:

  • [object,...] - ein Array mit Bound-Objekten (Dim ist dann die Anzahl von Objekten im Array)

  • object – ein Bound-Objekt (in diesem Fall ist Dim=1)

  • uint32 – Anzahl von Elementen bei einem Array mit Dim=1 und LBound=0

  • null: Bounds werden aus values berechnet

Ein Bound-Objekt hat folgende Form (LBound ist optional, in diesem Fall wird 0 verwendet):

{ LBound: 0, Elements: 3 }

Falls values vorhanden ist, dann muss es ein JS-Array sein. Dabei muss auch Dim=1 sein. Elemente aus dem JS-Array werden nach VARIANT konvertiert (rc.com.native.Variant kann auch verwendet werden), und mit SafeArrayPutElement in das SAFEARRAY einzeln eingetragen (Index fängt dabei mit 0 an). Elemente im SafeArray können nachträglich mit putElement geändert werden.

Folgende Methoden stehen zur Verfügung:

  • getVartype() : gibt VT_xx Typ des Array aus

  • getDim() : gibt Anzahl der Dimensionen aus

  • getElemsize() : gibt Größe des Elements in Bytes aus

  • getUBound(dim) : gibt UpperBound pro Dimension aus (dim startet mit 1)

  • getLBound(dim) : gibt LowerBound pro Dimension aus (dim startet mit 1)

  • getElement([indices]) :  gibt ein Array-Element als rc.com.native.Variant aus

  • putElement([indices],value) : setzt den Wert des entsprechenden Elements

  • ptrOfIndex([indices]) : gibt den Wert des Pointers auf die Daten des Elements aus

  • toJS() : konvertiert den Array in eine JS Variable

  • __dbgOutput() : erstellt eine Zusammenfassung vom SAFEARRAY in einer lesbaren Form

  • __binOutput() : gibt den binären Inhalt vom SAFEARRAY aus

indices – Array von Element-Indizes (bei Dim=1 ist es nur ein Index)

__dump(ptr,count)

Gibt binären Inhalt des Speichers aus. Diese Methode ist nur für Debugzwecke vorgesehen und kann sich in Zukunft ändern.

Parameter:

  • ptr : Adresse, s. z. B. __ptr oder ptrOfIndex()

  • count : Anzahl von Bytes

Rückgabewert: String mit Speicherinhalt

__ptr(object)

Ermittelt die Adresse des COM-Objekts. Diese Methode ist nur für Debugzwecke vorgesehen und kann sich in Zukunft ändern.

Parameter:

  • object : JS-Object mit COM-Inhalt (IDispatchIUnknownIEnumVARIANTVARIANTSAFEARRAY)

Rückgabewert: String mit hexadezimaler Darstellung der Adresse vom dem COM-Inhalt. Falls object ein natives JS-Objekt ist, und nicht aus oxv8 kommt, wird null zurück geliefert.

Beispielcode zur Verwendung von __ptr und __dump mit nachfolgendem Output:

Code

const dump = rc.com.native.__dump; const ptr = rc.com.native.__ptr; const o1 = new rc.com.ActiveXObject("oxv8.Test_Echo_Single_Ret"); rc.console.log("ptr(o1): " + ptr(o1) + " -> " + dump(ptr(o1),16)); const o2 = o1.F_disp_pure(o1); // liefert den Inputparameter einfach zurück rc.console.log("ptr(o2): " + ptr(o2) + " -> " + dump(ptr(o2),16)); rc.console.log("ptr(o1): " + ptr(o1) + " -> " + dump(ptr(o1),16)); rc.com.release(o1); rc.console.log("ptr(o2): " + ptr(o2) + " -> " + dump(ptr(o2),16)); rc.console.log("ptr(o1): " + ptr(o1));
ptr(o1): 0x00000000026B5500 -> E0 09 88 81 01 00 00 00-01 00 00 00 CD CD CD CD ptr(o2): 0x00000000026B5500 -> E0 09 88 81 01 00 00 00-02 00 00 00 CD CD CD CD ptr(o1): 0x00000000026B5500 -> E0 09 88 81 01 00 00 00-02 00 00 00 CD CD CD CD ptr(o2): 0x00000000026B5500 -> E0 09 88 81 01 00 00 00-01 00 00 00 CD CD CD CD ptr(o1): 0x0000000000000000   -------------------------------------------------------^^ Markiert ist hier anschaulich der RefCounter des COM-Objektes (diese Stelle hängt natürlich davon ab, wie das Objekt implementiert ist)

invoke(obj,invokeParams)

invoke macht einen COM-Aufruf, siehe auch: https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-idispatch-invoke.

  • obj : COM-Objekt, von dem die Methode aufgerufen wird

  • invokeParams : notwendige Information, um IDispatch::Invoke Aufruf zu machen. invokeParams muss beinhalten:

  • Kein Rückgabewert

Code

const invokeParams = {     memberID: getMemberID(obj,name),     flags: rc.com.native.INVOKE_FLAGS.METHOD,     isPropertyPut: false,     result: newVariant(),     params: [...] };

 

Related content