2009-07-14 44 views
18

Tôi đang làm việc trên một ứng dụng Java cần giao tiếp với ứng dụng C. Ứng dụng C sử dụng bộ nhớ chia sẻ và mmap để giao tiếp và tôi cần ứng dụng Java có quyền truy cập vào cùng một bộ nhớ. Lần đầu tiên tôi liên quan đến việc sử dụng các cuộc gọi JNI để lấy dữ liệu từ bộ nhớ chia sẻ, nhưng chi phí của mỗi cuộc gọi JNI bị giết, vì vậy tôi muốn có cách truy cập vào bộ nhớ đó trong Java và thực hiện truy xuất dữ liệu phía Java.Cách tốt nhất để truy cập bộ nhớ trong Java, tương tự như mmap là gì?

Ý tưởng tôi có là tôi sẽ cần phải làm như sau:

  1. Sử dụng một JNI cuộc gọi để có được vị trí của vị trí bộ nhớ chia sẻ tôi cần để đính kèm vào
  2. Tạo một FileChannel mới ()
  3. sử dụng rằng FileChannel để tạo ra một MappedByteBuffer sử dụng bản đồ()

đây có phải là cách tốt nhất để làm điều này? Ngoài ra, tôi không chắc chắn làm thế nào để thực sự tạo ra các FileChannel để trỏ vào vị trí bộ nhớ chính xác.

+0

Bạn không thể, nhưng tôi thích được sửa chữa – dfa

Trả lời

11

Xem xét sử dụng ByteBuffer.allocateDirect. Rõ ràng các bộ đệm này có thể được chuyển qua lớp JNI đến mã gốc có thể truy cập bộ nhớ trực tiếp.

Xem this page (trích dẫn dưới đây) cho gợi ý.

Bây giờ, mã JNI không chỉ có thể khám phá địa chỉ của không gian bộ nhớ riêng bên trong bộ đệm được tạo bởi ByteBuffer.allocateDirect() ở phía Java, nhưng nó có thể cấp phát bộ nhớ riêng của nó (ví dụ với malloc()) và sau đó gọi lại cho JVM để bọc không gian bộ nhớ đó trong đối tượng ByteBuffer mới (phương thức JNI để làm điều này là NewDirectByteBuffer()).

+1

điều này sẽ gần bằng kim loại như bạn có thể nhận được trong Java. Thật không may, ByteBuffer vẫn sẽ cần phải kéo thông tin qua biên giới VM. Nó có thể được hướng dẫn để có một cái nhìn tại cách JDK thực hiện Deflator - http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/Deflater.html –

+2

Tôi đã kết thúc bằng cách sử dụng ByteBuffers và họ đã làm việc rất tuyệt vời. Trong mã JNI, tôi đã tạo ra một ByteBuffer và trả về mã Java, sau đó có thể truy cập bộ nhớ đó trực tiếp. Cuối cùng, các ứng dụng Java của tôi có thể đọc được bộ nhớ và ghi vào nó. Các ghi chú sẽ hiển thị ngay lập tức với bất kỳ ứng dụng C/C++ nào sử dụng cùng một bộ nhớ. – Brian

-2

Nếu bạn có thể lưu dữ liệu vào tệp trong C và sau đó truy cập tệp từ Java, điều đó sẽ là tốt nhất. AFAIK bạn không thể chỉ vào bộ nhớ theo cách bạn muốn sử dụng Java.

+0

Điều này không đúng. Bộ đệm byte trực tiếp cung cấp khả năng mong muốn. –

0

Nếu bạn sở hữu cả các ứng dụng C và Java, họ chỉ có thể giao tiếp thông qua giao diện điều khiển dòng - xấu xí cho dữ liệu nhị phân nhưng có thể. Tôi sẽ trao đổi bộ nhớ dùng chung để có phong cách truyền tải thông điệp hơn - ví dụ: Cặp socket TCP/IP.

Btw, loại dữ liệu nào được truyền đi và dung lượng lớn như thế nào?

+0

Tôi không chắc chắn kích thước; có thể là khoảng 800Mb đến hơn một Gb. Thật không may, tôi không có sự thay đổi của ứng dụng C. – Brian

+0

Tạo một ứng dụng C mới bao bọc ứng dụng C ban đầu. Một khi bạn làm điều đó, giải pháp của kd304 hoặc giải pháp của AlbertoPL là có thể. – NamshubWriter

+0

Bạn luôn cần di chuyển toàn bộ dữ liệu giữa các ứng dụng? – akarnokd

1

tôi sẽ viết một module C nhỏ mmaps bộ nhớ chia sẻ và ổ cắm dùng để cho phép một ứng dụng khác để xem bộ nhớ đó (ví dụ như ứng dụng Java của bạn)

0

Không thể bạn viết một lớp Java với một số phương pháp tự nhiên, hãy viết triển khai phương thức gốc trong C để thực hiện những gì bạn muốn với mmap. Sau đó biên dịch nó thành một thư viện riêng và thêm nó vào thời gian chạy của bạn bằng cách sử dụng LD_LIBRARY_PATH. Điều này sẽ cho phép bạn thực hiện các cuộc gọi C bản địa trong Java mà không cần phí JNI (tôi nghĩ).

Một số hướng dẫn ở đây: link

Ví dụ, bạn sẽ viết một lớp Java như:

JMMap.java 

public class JMMap { 
    public native void write(...) 
} 

Sau đó chạy javah chống lại các tập tin lớp để tạo ra một cái gì đó như:

JMMap.h 

JNIEXPORT void JNICALL Java_JMMap_write(JNIEnv *, jobject); 

Triển khai tệp này trong tệp .c. Biên dịch nó thành một thư viện. Thêm nó vào đường dẫn LD, và sau đó chỉ cần gọi hàm Java.

Các vấn đề liên quan