Jna,指针已经映射到代理接口
Jna, Pointer already mapped to Proxy interface
我正在尝试 kotlin port of the openvr java binding 并将其更新为 1.0.3
我手动编写了所有方法,以确保 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)
根据this comment,似乎有多次调用特定的回调(GetEyeToHeadTransform_callback
?),但事实并非如此,我检查并仔细检查了代码,有一个和只有一个对该回调的引用..
还可能是什么?
编辑:
首先,当我 read()
在 IVRSysten
class 时发生这种情况,但我无法避免...
其次,我看到here之前的所有方法都获取真实地址,比如native@0x7fee4bebfd0
,只有GetEyeToHeadTransform
总是获取native@0xffffffff
...
编辑2:
调查原始代码
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
有不同的指针..
本机代码将 "magic" 值 -1
用于多个回调签名。编写 JNA 的回调代码时,假设将相同的函数指针映射到两个不同的签名应该是错误的。
我猜 -1
值的意思类似于 "use the default callback"(当可以说只是一个 NULL 指针可能就足够了,除非库使用 NULL 来指示不调用回调)。
当您看到 -1
值时,您可以通过将 Structure.read()
或 Structure.readField()
覆盖为 return 魔法值或常量回调对象来解决此问题,例如
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);
}
尽管这是一个老问题,但我还是想分享一下我的经验。在我的例子中,我有一个本机对象,它作为映射了代理方法的结构传递给 Java。该对象是某种会话,它实现了一个应该删除本机对象本身的关闭方法。一旦调用 close 并删除本机对象,就会抛出类似的异常。问题是在函数调用后 JNA 重新同步已删除的本机对象。这可以通过将自动读取设置为 false 来解决。
public void close(Handler handler) {
setAutoRead(false);
close.invoke(this, handler);
setAutoWrite(false);
}
我正在尝试 kotlin port of the openvr java binding 并将其更新为 1.0.3
我手动编写了所有方法,以确保 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)
根据this comment,似乎有多次调用特定的回调(GetEyeToHeadTransform_callback
?),但事实并非如此,我检查并仔细检查了代码,有一个和只有一个对该回调的引用..
还可能是什么?
编辑:
首先,当我 read()
在 IVRSysten
class 时发生这种情况,但我无法避免...
其次,我看到here之前的所有方法都获取真实地址,比如native@0x7fee4bebfd0
,只有GetEyeToHeadTransform
总是获取native@0xffffffff
...
编辑2:
调查原始代码
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
有不同的指针..
本机代码将 "magic" 值 -1
用于多个回调签名。编写 JNA 的回调代码时,假设将相同的函数指针映射到两个不同的签名应该是错误的。
我猜 -1
值的意思类似于 "use the default callback"(当可以说只是一个 NULL 指针可能就足够了,除非库使用 NULL 来指示不调用回调)。
当您看到 -1
值时,您可以通过将 Structure.read()
或 Structure.readField()
覆盖为 return 魔法值或常量回调对象来解决此问题,例如
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);
}
尽管这是一个老问题,但我还是想分享一下我的经验。在我的例子中,我有一个本机对象,它作为映射了代理方法的结构传递给 Java。该对象是某种会话,它实现了一个应该删除本机对象本身的关闭方法。一旦调用 close 并删除本机对象,就会抛出类似的异常。问题是在函数调用后 JNA 重新同步已删除的本机对象。这可以通过将自动读取设置为 false 来解决。
public void close(Handler handler) {
setAutoRead(false);
close.invoke(this, handler);
setAutoWrite(false);
}