Java 64 bit gọi C 32 bit

Chú ý:

  • Bài viết này trình bày chủ yếu cho CentOS 64 bit, tuy nhiên ý tưởng có thể áp dụng cho các hệ điều hành khác. Cuối bài có ghi chú cho Ubuntu.
  • Hệ điều hành 64 bit vẫn chạy/dùng được chương trình/thư viện 32 bit.

Giả sử ta muốn từ chương trình Java do ta viết gọi hàm gì đó trong thư viện viết bằng C. Nếu JVM và thư viện C đều cùng là 32 bit hoặc 64 bit thì quá khỏe, chỉ việc dùng JNA để nối trực tiếp thư viện vào chương trình (chạy 1 process).

JNA chỉ nối được sang thư viện động, không nối được sang thư viện tĩnh. Trên Linux 64 bit nếu có libXxx.a 32 bit, thì để chuyển sang libXxx.so 32 bit:
$ ar -x libXxx.a <-- giải nén .a thành các tập tin .o
$ gcc -m32 -shared *.o -o libXxx.so  <-- gom các tập tin .o lại thành .so

Tuy nhiên giả sử JVM là 64 bit còn thư viện là 32 bit, mà ta lại không có source code của thư viện để sửa và biên dịch lại theo chế độ 64 bit, thì chỉ còn cách cấu trúc theo kiểu client server (chạy 2 process).

Bài viết này giới thiệu cách dùng Thrift để đạt mục đích trên. (Dùng Thrift thì 2 process có thể nằm trên 2 máy khác nhau). Để hiểu bạn cần có căn bản Java và C++.

REST vs. RPC

Để liên lạc giữa các chương trình client và server viết bằng các ngôn ngữ khác nhau nằm trên các máy khác nhau có 2 trường phái chính, là dùng REST (thiên về data) và RPC (thiên về code). Khi chúng nằm trên cùng mạng nội bộ của cùng một công ty, nơi công ty có thể toàn quyền điều khiển cả 2 đầu client và server, muốn thay đổi interface giữa chúng lúc nào thì thay đổi, thì RPC dựa trên cách đóng gói dữ liệu kiểu binary thường được ưa thích hơn vì tiện lập trình và cho tốc độ rất cao.

Hiện nay tiêu biểu cho trường phái RPC là là Protocol Buffers và Thrift. Chúng cho tốc độ cao hơn hẳn so với những cách đóng gói theo kiểu text đã lỗi thời như XML-RPC và SOAP. Với những công ty có server nhiều đến mức đếm không xuể như Google và Facebook, thì tốc độ nhanh hơn vài ms đã là rất đáng kể.

Cài Thrift ở chế độ hỗ trợ Java và C++ 32 bit

Thrift hỗ trợ nhiều ngôn ngữ, trong đó có Java và C++. Để hỗ trợ Java Thrift cần thêm ant, để hỗ trợ C++ Thrift cần thêm Boost.

$ sudo yum install ant
$ sudo yum install boost-devel.i386

Chuẩn bị những thứ trên xong, ta download và giải nén Thrift vào /src/thrift-0.6.0-i386. Ta sẽ biên dịch và cài vào /opt/thrift-0.6.0-i386:

$ cd /src/thrift-0.6.0-i386
$ CFLAGS=-m32 LDFLAGS=-m32 CPPFLAGS=-m32 CXXFLAGS=-m32 YFLAGS=-m32 JAVA_PREFIX=/opt/thrift-0.6.0-i386/lib/java ./configure --prefix=/opt/thrift-0.6.0-i386 --with-perl=no --with-php=no --with-php_extension=no --with-python=no --with-ruby=no --with-haskell=no --with-erlang=no

Kết quả hiện trên màn hình:

thrift 0.6.0

Building code generators ..... : cpp c_glib java as3 csharp py rb perl php erl cocoa st ocaml hs xsd html js javame

Building C++ Library ......... : yes
Building C (GLib) Library .... : no
Building Java Library ........ : yes
Building C# Library .......... : no
Building Python Library ...... : no
Building Ruby Library ........ : no
Building Haskell Library ..... : no
Building Perl Library ........ : no
Building PHP Library ......... : no
Building Erlang Library ...... : no

Building TZlibTransport ...... : yes
Building TNonblockingServer .. : no

Using javac .................. : javac
Using java ................... : java
Using ant .................... : /usr/bin/ant

Tiếp tục:

$ make
$ sudo make install

Vì hệ điều hành đang là CentOS 64 bit, nên cần tham số -m32 để ép chế độ 32 bit. Ngoài ra vì chỉ cần Java và C++, không cần những ngôn ngữ xxx khác nên ta đặt --with-xxx=no.

Chạy thử chương trình ví dụ C++

Thư mục /src/thrift-0.6.0-i386/tutorial là thư mục chứa các ví dụ. Ta sẽ chạy thử ví dụ C++.

Trước hết cần sinh ra tự động các tập tin C++ cần thiết từ tutorial.thrift:

$ cd /src/thrift-0.6.0-i386/tutorial
$ /opt/thrift-0.6.0-i386/tutorial/bin/thrift -r --gen-cpp tutorial.thrift

Thư mục gen-cpp sẽ được tạo ra.

Tiếp theo ta biên dịch chương trình ví dụ client và server nằm trong thư mục cpp. Tuy nhiên phải sửa tập tin Makefile trong đó một chút để ứng với cấu hình 32 bit và thư mục /opt/thrift-0.6.0-i386:

BOOST_DIR  = /opt/local/include
THRIFT_DIR = /opt/thrift-0.6.0-i386/include/thrift
LIB_DIR = /opt/thrift-0.6.0-i386/lib

GEN_SRC = ../gen-cpp/SharedService.cpp ../gen-cpp/shared_types.cpp ../gen-cpp/tutorial_types.cpp ../gen-cpp/Calculator.cpp

default: server client

server: CppServer.cpp
g++ -m32 -o CppServer -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppServer.cpp ${GEN_SRC}

client: CppClient.cpp
g++ -m32 -o CppClient -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppClient.cpp ${GEN_SRC}

clean:
$(RM) -r CppClient CppServer

Cái quan trọng là đường dẫn thư mục và tham số -m32.

Sửa xong ta biên dịch là chạy được:

$ cd /src/thrift-0.6.0-ỉ86
$ make
$ ./CppServer
Starting the server...

Mở cửa sổ console khác, chạy CppClient sẽ thấy kết quả.

Java 64 bit gọi C 32 bit

Trên đây là ví dụ trong đó cả server và client đều là C++. Vì Java được gọi là "write once, run anywhere", chương trình Java viết xong chạy được trên cả JVM 32 bit và 64 bit, nên tham khảo thêm mã nguồn của ví dụ C++ và Java là biết cách viết phần server và client đệm giữa chương trình Java và thư viện C để đạt mục đích đề ra:

  Process 32 bit      Process JVM 64 bit
+---------------+ +---------------+
| Thư viện C | | Ch.trình Java |
| | | | | |
| (de)serialize | | (de)serialize |
| | | | | |
| C++ client |-RPC-| Java server |
+---------------+ +---------------+

Ubuntu

Phần trên trình bày cho CentOS 64 bit. Trên Ubuntu 10.10 64 bit, cần cài gói g++-multilib trước khi chạy lệnh configure khi cài Thrift. Gói g++-multilib làm cho tham số -m32 có hiệu lực.

Chú ý theo bình luận ở đây, để sau khi cài g++-multilib, cần chạy lệnh:

$ sudo ln -s /usr/lib32/libstdc++.so.6 /usr/lib32/libstdc++.so

Đọc thêm

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Ngoc Dao

102 bài viết.
252 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
56 6
Làm thế nào để nâng cấp trang web mà không làm gián đoạn dịch vụ? Đây là câu hỏi phỏng vấn các công ty lớn thường hỏi khi bạn xin vào vị trí làm lậ...
Ngoc Dao viết 2 năm trước
56 6
White
32 0
Bài viết này giải thích sự khác khác nhau giữa hai ngành khoa học máy tính (computer science) và kĩ thuật phần mềm (software engineering), hi vọng ...
Ngoc Dao viết gần 2 năm trước
32 0
White
28 1
Nếu là team leader, giám đốc công ty hay tướng chỉ huy quân đội, vấn đề cơ bản bạn gặp phải là “hướng mọi người đi theo con đường bạn chỉ ra”. Thử...
Ngoc Dao viết gần 2 năm trước
28 1
Bài viết liên quan
White
1 14
(Ảnh) Khi cài đặt mysql trên CentOS 6 theo hướng dẫn tại (Link) với dòng lệnh: yum install mysqlserver lúc chạy câu lệnh service mysqld start bị...
Vũ Hoàng Chung viết gần 3 năm trước
1 14
White
7 1
Ngày xửa ngày xưa ... Ngày mới chập chững bước vào nghề System Engineer , được sếp hướng dẫn và giao cho task : compile HTTPD, PHP lên Server. Lúc...
Ha Nguyen viết gần 2 năm trước
7 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
102 bài viết.
252 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!