2013-03-14 17 views
15

Moim celem jest przekazanie danych z procesu C++ do procesu Java, a następnie otrzymanie wyniku z powrotem.Wspólna pamięć między procesami C++ i Java

Osiągnąłem to dzięki nazwanej fajce, ale wolałbym udostępniać dane zamiast je przekazywać lub kopiować, zakładając, że dostęp będzie szybszy.

Początkowo myślałem o stworzeniu wspólnego segmentu w C++, który mógłbym napisać i czytać z Javą, ale nie jestem pewien, czy jest to możliwe przez JNI, nie mówiąc już o bezpieczeństwie.

wierzę, że to możliwe w Javie przydzielić pamięci za pomocą ByteBuffer.allocateDirect a następnie użyć GetDirectBufferAddress dostęp do adresu w C++, ale jeśli się nie mylę to jest dla rodzimych połączeń w JNI i nie mogę dostać tego adresu w moim procesie C++?

Utracone.

Wielkie dzięki z góry.

Odpowiedz

4

Czy rozważałeś użycie 0MQ obsługuje zarówno Java i C++ i będzie bardziej niezawodny. Myślę, że jeśli chcesz robić pamięć współdzieloną w Javie, to musiałbyś to robić przez JNI, ostatni raz, gdy patrzyłem, nie było innego sposobu, żeby to zrobić.

To pokazuje, że musisz to zrobić przez JNI, jeśli jedziesz tą trasą. Chociaż znalezione przeze mnie rozwiązania są specyficzne dla systemu Windows, które mogą nie dotyczyć użytkownika.

13

Jeśli masz pamięć współużytkowaną, na przykład używając CreateFileMapping (Windows) lub shmget (Unix), wszystko, czego potrzebujesz, to natywna metoda po stronie Java. Następnie można utworzyć ByteBuffer że bezpośrednio dostęp do pamięci współdzielonej korzystając NewDirectByteBuffer takiego:

JNIEXPORT jobject JNICALL Java_getSharedBuffer(JNIEnv* env, jobject caller) { 
    void* myBuffer; 
    int bufferLength; 

Teraz trzeba uzyskać wskaźnik do pamięci współdzielonej. W systemie Windows należy użyć coś takiego:

bufferLength = 1024; // assuming your buffer is 1024 bytes big 
    HANDLE mem = OpenFileMapping(FILE_MAP_READ, // assuming you only want to read 
      false, "MyBuffer"); // assuming your file mapping is called "MyBuffer" 
    myBuffer = MapViewOfFile(mem, FILE_MAP_READ, 0, 0, 0); 
    // don't forget to do UnmapViewOfFile when you're finished 

Teraz można po prostu stworzyć ByteBuffer że jest poparta tej wspólnej pamięci:

// put it into a ByteBuffer so the java code can use it 
    return env->NewDirectByteBuffer(myBuffer, bufferLength); 
} 
Powiązane problemy