2016-10-20 4 views
2

Я пытаюсь сделать kotlin port в openvr java binding, а также обновить его 1.0.3ЮНА, указатель уже отображается в интерфейсе Proxy

я получил в момент написания IVRSystem struct/class

Я написал все методы вручную, чтобы убедиться, что не будет какой-либо ошибки из автоматического переводчика в Intellij

Я избавилась от всех ошибок, исходящих из различного числа полей от getFieldOrder(), но теперь я все еще получаю ошибку:

Exception in thread "main" java.lang.IllegalStateException: Pointer [email protected] already mapped to Proxy interface to native [email protected] (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?), Но это не так, я проверил и дважды проверил код, есть один и только один ссылка на этот обратный вызов ..

что еще может быть?

Edit:

первый, это происходит, когда я read() на IVRSysten классе, но я не могу избежать этого ...

второй, я вижу, что here все предыдущие методы получить реальные адреса, такие а [email protected] только GetEyeToHeadTransform получает всегда [email protected] ...

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

Родной код использует "волшебную" значение -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); 
} 
+0

Спасибо Тимоти, я решил [следующим образом] (https://github.com/elect86/openvr/blob/master/src/vr.kt#L2093-L2105), но теперь я получаю еще два поля с '0xfa0' и еще пару полей с другим указателем ... Невозможно, чтобы это была ошибка на стороне jna, не так ли? В любом случае, я открыл [выпуск] (https://github.com/ValveSoftware/openvr/issues/299) на клапане openvr github, давайте посмотрим, что случилось .. – elect

+0

Я обновил вопрос .. – elect

+0

Вполне возможно, что 'openvr' просто повторно использует обратный вызов, или это может быть другое волшебное значение (0xfa0 не похож на действительный указатель на функцию). Если вам действительно не нужно устанавливать или вызывать данный обратный вызов, просто определите его как «Указатель». – technomage

 Смежные вопросы

  • Нет связанных вопросов^_^