2

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?) への複数の呼び出しがあるように見えますが、そうではありません。コードを確認して再確認しました。そのコールバックへの参照は 1 つだけです。

他に何がありますか?

編集:

read()まず、これは私が授業中に起こるのですがIVRSysten、それを避けることはできません...

第二に、ここでは、以前のすべてのメソッドが実際のアドレスを取得し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

GetEyeToHeadTransformGetSeatedZeroPoseToStandingAbsoluteTrackingPose異なるポインタを持っています..

4

2 に答える 2

1

-1ネイティブ コードは、複数のコールバック シグネチャに対しての「マジック」値を使用しています。この JNA 用のコールバック コードが作成されたとき、同じ関数ポインタを 2 つの異なるシグネチャにマップするとエラーになると想定されていました。

その-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);
}
于 2016-10-21T18:34:48.693 に答える
0

これは古い質問ですが、私の経験を共有したいと思います。私の場合、プロキシ メソッドがマップされた構造体として Java に渡されるネイティブ オブジェクトがあります。オブジェクトは、ネイティブ オブジェクト自体を削除する必要がある close メソッドを実装するある種のセッションです。close が呼び出されてネイティブ オブジェクトが削除されるとすぐに、同様の例外がスローされます。問題は、関数呼び出しの後、JNA が削除されたネイティブ オブジェクトを再同期することです。これは、自動読み取りを false に設定することで解決できます。

public void close(Handler handler) {
    setAutoRead(false);
    close.invoke(this, handler);
    setAutoWrite(false);
}
于 2019-10-28T12:06:32.960 に答える