2016-07-04 9 views
0

JNA에서 Microsoft AutomationClient COM 컨트롤을 호출 할 때 발생하는 문제를 격리하려고합니다.JNA를 통해 COM 인터페이스를 호출 할 때 잘못된 메모리 액세스 예외가 발생했습니다.

내가 전체 라이브러리에 대한 핸들러 만든 : 내가 전화

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

:

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; 
    } 

을하고 난 COM 메서드를 호출 할 방법을 작성했습니다 (이 작동하는 예입니다) 다른 두 개의 속성을 취하는 CreateAndCondition 메서드는 다음과 같은 또 다른 속성을 반환합니다.

public void CreateAndCondition(Pointer condition0, Pointer condition1, PointerByReference condition) { 

    int result = this._invokeNativeInt(25, new Object[]{this.getPointer(), condition0, condition1, condition}); 
    COMUtils.checkRC(new WinNT.HRESULT(result)); 
} 
다음 코드는 추출만큼 내가 할 수있는 단순화 된 363,210

.. 나는 다음과 같은 스택 추적을 얻을

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); 

:

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) 

델파이과 오래 된이 코드의 버전을 작성한을 버전 com4jna 라이브러리를 사용하지만,이 날 패배 것 같습니다.

그래서 내가 뭘 잘못하고 있니?

UPDATE 사전에

감사합니다 : 나는 문제 (아래로)을 변형 걸리는 GetPropertyCondition의 정의에 실제로 있다고 생각합니다.

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)); 
} 

반환되는 개체의 I QueryInterface를 사용하면 동일한 오류가 발생합니다. COM을 통해 변형을 마샬링하는 것과 관련이 있습니다.

답변

1

몇 가지 잘못했다,하지만 호출 코드가 더 다음과 같이한다 : CreateAndCondition이 .getValue()보다는 .getPointer 인에 변형이 아니라 ByReferece보다 ByValue 인으로

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); 

및 입력()