2016-07-04 18 views
0

Ich versuche, ein Problem zu isolieren, wenn ich das MS AutomationClient COM-Steuerelement von JNA aufrufen.Ungültige Speicherzugriff Ausnahme beim Aufrufen der COM-Schnittstelle über JNA

ich einen Handler für die gesamte Bibliothek erstellt haben:

public static UIAutomationHandler create() { 
    Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_APARTMENTTHREADED); 
    PointerByReference pbr = new PointerByReference(); 
    WinNT.HRESULT hr = Ole32.INSTANCE.CoCreateInstance(
      CLSID_CUIAutomation, 
      null, 
      WTypes.CLSCTX_SERVER, 
      IID_IUIAutomation, 
      pbr); 
    COMUtils.checkRC(hr); 
    UIAutomationHandler tb = new UIAutomationHandler(pbr.getValue()); 
    return tb; 
    } 

und ich habe Methoden geschrieben, dass die COM-Methoden aufrufen (dies ist ein Beispiel, das funktioniert):

public void GetRootElement(PointerByReference elt) { 
    int result = this._invokeNativeInt(5, new Object[]{this.getPointer(), elt}); 
    COMUtils.checkRC(new WinNT.HRESULT(result)); 
} 

Wenn ich rufe die CreateAndCondition-Methode, die 2 andere Eigenschaften akzeptiert und eine andere Eigenschaft zurückgibt, die folgendermaßen aussieht:

Der folgende Code wurde ..

PointerByReference pbr0 = new PointerByReference(); 
PointerByReference pbr1 = new PointerByReference(); 
PointerByReference pbr = new PointerByReference(); 

Variant.VARIANT var1 = new Variant.VARIANT.ByReference(); 
Variant.VARIANT var2 = new Variant.VARIANT.ByReference(); 

var2.setValue(Variant.VT_INT, ControlType.Window); 
var1.setValue(Variant.VT_BSTR, sysAllocated); 

this.handler.CreatePropertyCondition(PropertyID.Name.getValue(), var1, pbr0); 
this.handler.CreatePropertyCondition(PropertyID.ControlType.getValue(), var2, pbr1); 
this.handler.CreateAndCondition(pbr0.getPointer(), pbr1.getPointer(), pbr); 

ich folgende Stack-Trace erhalten extrahiert und so viel wie ich kann vereinfacht:

Exception in thread "main" java.lang.Error: Invalid memory access 
    at com.sun.jna.Native.invokeInt(Native Method) 
    at com.sun.jna.Function.invoke(Function.java:386) 
    at com.sun.jna.Function.invoke(Function.java:321) 
    at com.sun.jna.Function.invoke(Function.java:276) 
    at com.sun.jna.Function.invoke(Function.java:267) 
    at com.sun.jna.Function.invokeInt(Function.java:674) 
    at com.sun.jna.platform.win32.COM.COMInvoker._invokeNativeInt(COMInvoker.java:27) 
    at mmarquee.automation.uiautomation.impl.UIAutomationHandler.CreateAndCondition(UIAutomationHandler.java:82) 
    at mmarquee.automation.UIAutomation.getDesktopWindow(UIAutomation.java:205) 
    at mmarquee.automation.TestMainWPF.run(TestMainWPF.java:57) 
    at mmarquee.automation.MainWPF.main(MainWPF.java:23) 

Ich habe Versionen dieses Codes für Delphi geschrieben und eine alte Version, die die com4jna-Bibliothek verwendet, aber das scheint mich besiegt zu haben.

Also, was mache ich falsch?

Vielen Dank im Voraus

UPDATE: Ich glaube, dass das Problem tatsächlich in der Definition des GetPropertyCondition, das eine Variante (wie unten) führt.

public void CreatePropertyCondition(int propertyId, Variant.VARIANT value, PointerByReference elt) { 
     int result = this._invokeNativeInt(UIA_CREATE_PROPERTY_CONDITION, new Object[]{this.getPointer(), propertyId, value, elt}); 
     COMUtils.checkRC(new WinNT.HRESULT(result)); 
} 

Wenn ich QueryInterface auf das zurückgegebene Objekt, dann bekomme ich den gleichen Fehler. Es hat also etwas damit zu tun, die Variante via COM zu marshallen.

Antwort

1

Mehrere Dinge waren falsch, aber der anrufende Code sollte wie folgt aussehen:

Variant.VARIANT.ByValue var1 = new Variant.VARIANT.ByValue(); 
Variant.VARIANT.ByValue var2 = new Variant.VARIANT.ByValue(); 

var2.setValue(Variant.VT_INT, ControlType.Window); 
var1.setValue(Variant.VT_BSTR, sysAllocated); 

this.handler.CreatePropertyCondition(PropertyID.Name.getValue(), var1, pbr0); 
this.handler.CreatePropertyCondition(PropertyID.ControlType.getValue(), var2, pbr1); 
this.handler.CreateAndCondition(pbr0.getValue(), pbr1.getValue(), pbr); 

Mit den Varianten ByValue statt ByReferece und Eingang CreateAndCondition sein .getValue(), anstatt .getPointer sein()