Jna,指针已经映射到代理接口
我正在尝试做openvr java绑定的kotlin端口 ,并将其更新到1.0.3
我已经着手编写IVRSystem
结构/类
我手动编写了所有的方法,以确保Intellij中的自动翻译器不会有任何错误
我摆脱了来自getFieldOrder()
不同字段的所有错误,但是现在仍然出现错误:
Exception in thread "main" java.lang.IllegalStateException: Pointer native@0xffffffff already mapped to Proxy interface to native function@0xffffffff (IVRSystem$GetEyeToHeadTransform_callback). Native code may be re-using a default function pointer, in which case you may need to use a common Callback class wherever the function pointer is reused. at com.sun.jna.CallbackReference.getCallback(CallbackReference.java:124) at com.sun.jna.CallbackReference.getCallback(CallbackReference.java:107) at com.sun.jna.Pointer.getValue(Pointer.java:430) at com.sun.jna.Structure.readField(Structure.java:705) at com.sun.jna.Structure.read(Structure.java:565) at IVRSystem.<init>(vr.kt:2091) at VrKt.VR_Init(vr.kt:2116) at VrKt.main(vr.kt:2133) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
根据这个评论 ,它看起来像有多个调用一个特定的回调( GetEyeToHeadTransform_callback
?),但它不是,我检查和双重检查的代码,只有一个引用到该回调..
还有什么呢?
编辑:
首先,当我read()
IVRSysten
类时发生这种情况,但我无法避免这种情况…
第二,我看到, 在这里所有以前的方法得到真正的地址,如native@0x7fee4bebfd0
,只有GetEyeToHeadTransform
得到总是native@0xffffffff
…
EDIT2:
调查原始代码
dprintf("GetRecommendedRenderTargetSize %p\n", &vr::IVRSystem::GetRecommendedRenderTargetSize); dprintf("GetProjectionMatrix %p\n", &vr::IVRSystem::GetProjectionMatrix); dprintf("GetProjectionRaw %p\n", &vr::IVRSystem::GetProjectionRaw); dprintf("ComputeDistortion %p\n", &vr::IVRSystem::ComputeDistortion); dprintf("GetEyeToHeadTransform %p\n", &vr::IVRSystem::GetEyeToHeadTransform); dprintf("GetTimeSinceLastVsync %p\n", &vr::IVRSystem::GetTimeSinceLastVsync); dprintf("GetD3D9AdapterIndex %p\n", &vr::IVRSystem::GetD3D9AdapterIndex); dprintf("GetDXGIOutputInfo %p\n", &vr::IVRSystem::GetDXGIOutputInfo); dprintf("IsDisplayOnDesktop %p\n", &vr::IVRSystem::IsDisplayOnDesktop); dprintf("SetDisplayVisibility %p\n", &vr::IVRSystem::SetDisplayVisibility); dprintf("GetDeviceToAbsoluteTrackingPose %p\n", &vr::IVRSystem::GetDeviceToAbsoluteTrackingPose); dprintf("ResetSeatedZeroPose %p\n", &vr::IVRSystem::ResetSeatedZeroPose); dprintf("GetSeatedZeroPoseToStandingAbsoluteTrackingPose %p\n", &vr::IVRSystem::GetSeatedZeroPoseToStandingAbsoluteTrackingPose);
打印出来
GetRecommendedRenderTargetSize 0109871D GetProjectionMatrix 0109AACC GetProjectionRaw 0109AAD1 ComputeDistortion 0109AAF9 GetEyeToHeadTransform 0109AAC2 GetTimeSinceLastVsync 0109AAE5 GetD3D9AdapterIndex 0109AAF4 GetDXGIOutputInfo 0109AADB IsDisplayOnDesktop 0109AAEA SetDisplayVisibility 0109AAE0 GetDeviceToAbsoluteTrackingPose 0109AAEF ResetSeatedZeroPose 0109AAD6 GetSeatedZeroPoseToStandingAbsoluteTrackingPose 0109AAC7
GetEyeToHeadTransform
和GetSeatedZeroPoseToStandingAbsoluteTrackingPose
有不同的指针
本机代码使用-1
的“魔术”值来表示多个回调签名。 当这个JNA的回调代码被写入时,假定把相同的函数指针映射到两个不同的签名应该是错误的。
我猜测-1
值意味着像“使用默认回调”(当可以简单地指出NULL指针可能已经足够,除非库使用NULL来指示不要调用回调)。
你可以通过重写Structure.read()
或者Structure.readField()
来返回一个魔术值或者常量回调对象,当你看到-1
值时,例如
public void read() { Memory old = getPointer(); Memory m = autoAllocate(size()); // horribly inefficient, but it'll do m.write(0, old.getByteArray(0, size()), 0, size()); useMemory(m); // Zero out the problematic callbacks for (field : problematic_fields) { m.setPointer(field_offset, null); } super.read(); useMemory(old); }