Kod Java:

package library;

import java.nio.ByteBuffer;

public class Library
{    
    static{System.loadLibrary("TestDLL");}

    native static void GetGLBuffer(ByteBuffer Buffer, int Width, int Height, int Size);

    public static void main(String[] args) {

        ByteBuffer B = ByteBuffer.allocateDirect(5);
        byte[] C = {'H', 'E', 'R', 'E', '\0'};
        B.put(C);
        GetGLBuffer(B, 0, 0, 4);
        System.out.println((char)B.get(0));
    }
}

Code C ++:

JNIEXPORT void JNICALL Java_library_Library_GetGLBuffer(JNIEnv *env, jclass cls, jobject buffer, jint Width, jint Height, jint Size)
{
    unsigned char* Buff = (unsigned char*)env->GetDirectBufferAddress(buffer);
    //*Buff = 'A'; Crashes it.
    //Buff[0] = 'A'; Crashes it.
    //std::cout<<Buff[0]; Prints fine but crashes when this function ends.
}

Jeśli nic nie zrobię, to działa idealnie. Ponadto, jeśli zadeklaruję zmienne w ramach powyższej funkcji, zawiesza się.

Jak to naprawić? Czy robię coś złego?

Drukuje ten plik: http://pastebin.com/Mz76Bk8G

2
Brandon 30 wrzesień 2012, 23:40

2 odpowiedzi

Najlepsza odpowiedź

Chcę tylko powiedzieć, że rozwiązałem to. Musiałem przejść do mojego folderu JNI, skopiować JNI.hi JNI_MD.h for JDK 7 do mojego folderu projektu C++, dołączyć go jako plik, a także użyć pliku .def do eksportu.

Bez wykonania wszystkich powyższych kroków spowodował awarię JVM. Teraz nie wiem dlaczego, ale cieszę się, że to działa. Publikuję to, aby inni, którzy mają ten sam problem, mogli go naprawić.

Dzięki za poglądy chłopaki. Trudno było się zorientować, co jest nie tak. Mam nadzieję, że ten komentarz pomoże innym.

0
Brandon 1 październik 2012, 00:17

Problem polega na tym, że nie przekazujesz tablicy bajtów do funkcji C, ale raczej obiekt ByteBuffer. Aby ustawić wartości wewnątrz bufora, musisz wywołać metody na obiekcie bufora, co w języku C oznacza zapytanie obiektu o jego klasę, zapytanie klasy o właściwą metodę, a następnie wywołanie metody.

Na przykład, jeśli chciałbyś wykonać równoważne wywołanie metody put(int index, byte b) na obiekcie ByteBuffer, musiałbyś zrobić coś takiego w swoim kodzie C:

jclass cls = (*env)->GetObjectClass(env, objID);
jmethodId mid = (*env)->GetMethodID(env, cls, "put","(IB)V");
if(mid == 0) return;
(*env)->CallVoidMethod(env, objID, mid, 0, 'A');
0
Darius Makaitis 1 październik 2012, 00:20