0

さて、私はこのゲームを持っていて、dll からバッファを読み取る JNI クラスを書きました。そのため、byteBuffer または intBuffer を DLL に渡すと、ピクセル (RGB 配列) で埋められます。

私はそれを次のように使用します:

GLDXLoader GLDXPlugin = new GLDXLoader(null, 0, 0);

if (GLDXLoader.OpenGLLoaded) {
    GLDXPlugin.setMode(OperatingMode.OpenGL);
    GLDXPlugin.GetBuffer(gameBuffer);  //GetBuffer called..
}

しかし、私がそれを呼び出すと、クラッシュします..ただし、そうすると:

GLDXLoader GLDXPlugin = new GLDXLoader(null, 0, 0);

if (GLDXLoader.OpenGLLoaded) {
    GLDXPlugin.setMode(OperatingMode.OpenGL);
    GLDXLoader.GetOpenGLBuffer(gameBuffer);  //GetOpenGLBuffer called..
}

それは問題なく動作します..したがって、最初の呼び出しで間違っていることがわかる唯一のことは、ネイティブ関数に渡す関数に IntBuffer が渡され、仲介者が JVM をクラッシュさせることです。

私のクラスは次のとおりです。

package JNI;

import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import smart.OperatingMode;

public class GLDXLoader {

    private int ByteSize = 0;
    private IntBuffer IBuffer = null;
    private ByteBuffer BBuffer = null;
    private OperatingMode Mode = null;
    private BufferedImage Image = null;
    public static boolean OpenGLLoaded = false;
    public static boolean DirectXLoaded = false;
    //ByteSize = ((ImageWidth * BitsPerPixel + 31) / 32) * 4 * ImageHeight;

    public static native void GetOpenGLBuffer(IntBuffer Buffer);

    private static native void GetDirectXBuffer(IntBuffer Buffer);

    public GLDXLoader(ByteBuffer Buffer, int ImageWidth, int ImageHeight) {
        if (Buffer != null) {
            this.BBuffer = Buffer;
            this.IBuffer = BBuffer.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
        }
    }

    public GLDXLoader(int ImageWidth, int ImageHeight) {
        ByteSize = ImageWidth * ImageHeight * 4;
        BBuffer = ByteBuffer.allocateDirect(ByteSize).order(ByteOrder.LITTLE_ENDIAN);
        IBuffer = BBuffer.asIntBuffer();
    }

    private void readBuffer(IntBuffer Buffer, OperatingMode Mode) {
        Buffer.rewind();
        switch (Mode) {
            case OpenGL:
                GetOpenGLBuffer(Buffer);
            case DirectX:
                GetDirectXBuffer(Buffer);
            default:
                break;
        }
    }

    public void setMode(OperatingMode Mode) {
        this.Mode = Mode;
    }

    public void GetBuffer(IntBuffer Buffer) {
        readBuffer(Buffer, Mode);
    }
}

C++ コード:

void JNIData::FlipBytes(void*& Result) //Copies my Bitmap Bytes in reverse order.. Flips the Bitmap Upside down and stores it in "Result".
{
   unsigned long Chunk = (Bpp > 24 ? width * 4 : width * 3 + width % 4);
   unsigned char* Destination = static_cast<unsigned char*>(Result);
   unsigned char* Source = &BufferPixels[0] + Chunk * (height - 1);

   while(Source != &BufferPixels[0])
   {
      std::memcpy(Destination, Source, Chunk);
      Destination += Chunk;
      Source -= Chunk;
   }
}

extern "C" JNIEXPORT void JNICALL Java_JNI_GLDXLoader_GetOpenGLBuffer(JNIEnv *Env, jclass Cls, jobject Buffer)
{
    //jclass IntBufferClass = Env->FindClass("java/nio/IntBuffer");
    //jmethodID Rewind = Env->GetMethodID(IntBufferClass, "rewind", "()Ljava/nio/Buffer;");
    //Env->CallObjectMethod(Buffer, Rewind);
    void* CBuff = Env->GetDirectBufferAddress(Buffer);
    JNIBuffer.FlipBytes(CBuff);
}

誰かが私を助けたり、仲介者関数 (GetBuffer) がクラッシュする理由を説明したりできますか?

4

0 に答える 0