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