さて、私はこのゲームを持っていて、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) がクラッシュする理由を説明したりできますか?