Copyright (c) 1999 Yoon Kyung Koo, All rights reserved.
자바 프로그램과 C/C++ 프로그램 사이에 데이터 통신(주로 소켓을 사용하겠지요...)을 할 때에는 자바의 객체 스트림(java.io.Serializable or java.io.Externalizable을 인터페이스를 구현하고 ObjectInput/OutputStream 사용)을 사용할 수가 없습니다. 자바의 객체 스트림은 자바에 고유한 형식을 사용하기 때문에 C/C++ 프로그램이 이해할 수 없기 (어렵기?) 때문입니다. 따라서 자바와 C/C++ 프로그램 사이에서 데이터를 주고 받으려면 기본 유형으로 변환하여 주고 받을 수밖에 없습니다. 예를 들어 다음과 같은 필드들로 구성된 자바 클래스를 C/C++ 프로그램과 주고 받는다고 생각해봅시다. class TestData { byte[] bytes = new byte[100] ; char c; // assume this char value will not excced one byte (i.e. cannot use Hangul char) boolean val; String string; } 대응되는 C/C++ 데이터 구조체를 다음과 같이 생각할 수 있겠습니다. typedef struct { char bytes[100]; char c; // 물론 이렇게 구현하면 안됩니다. C의 구조체 alignment에 따라 // 사용되지 않는 몇 바이트가 채워지게 됩니다. bool val; // 보통 C++의 bool 유형은 int처럼 4바이트지만 컴파일러와 O/S에 따라 다릅니다. // 예를 들어 64비트 머신인 디지털 유닉스 4.0의 g++ 2.95에서 bool은 8바이트를 // 차지합니다. (같은 기계에서 cxx의 경우 4바이트를 차지합니다.) int str_length; // 문자열의 길이 char * string; } Object ; 이럴 경우에 발생하는 문제는 여러 가지가 있을 수 있습니다. 1. C/C++에서 structure가 차지하는 각 필드들의 바이트 수... 위의 경우처럼 char가 중간에 혼자 들어가게 되면 3바이트가 덧붙는 경우가 생기게 됩니다. 2. 각 기본 유형들의 데이터 길이... 자바는 고정되어 있지만 C/C++의 경우에는 컴파일러와 O/S 등에 따라 차이가 납니다. 예를 들어 long의 경우 자바는 8바이트이지만 C/C++의 경우 운영 체제에 따라 4바이트와 8바이트가 각각 사용될 수 있습니다. GNU의 C/C++ 컴파일러를 사용하면 8바이트 유형인 long long를 사용하여 자바의 long에 대응시킬 수 있습니다. 위 예제에서는 bool 유형(보통 4바이트지만 어떤 컴파일러/운영체제에서는 8바이트로 처리), int 유형(16비트 운영체제에서는 2바이트로 처리), char *와 같은 주소 유형(CPU 종류에 따라 2바이트, 4바이트, 8바이트 등으로 처리) 등이 C/C++ 쪽에서 주의해야 할 유형입니다. 3. short, int, long 등의 바이트 순서 자바는 네트웍 순서(빅 엔디안)로 고정되어 있지만 C/C++의 경우에는 CPU 유형에 따라 달라지므로 반드시 보정해줘야 합니다. 만약 자바쪽에서 리틀 엔디안으로 변환하여 보내려면 htonl/htons 기능을 하는 메소드를 구현하여야 합니다. 참고 : 자바 기본 유형의 바이트 순서 변환 4. char의 인코딩... 자바는 String을 내부적으로 유니코드를 사용하니까 바이트로 변환하여 C/C++와 주고받아야 합니다. 특히 한글과 같은 2바이트 문자를 사용할 때에는 더욱 중요합니다. DataOutput 혹은 ObjectOutput의 void writeBytes(String)과 같은 메소드는 무조건 문자를 1바이트로 처리하여 쓰므로 2바이트 문자가 사용될 경우에는 사용하지 말아야 할 메소드입니다. (String의 length()와 문자열을 바이트열로 변환한 byte[]의 length 값이 다를 수 있다는 건 아시지요?)다음은 간단한 예제입니다. 소켓 프로그램으로 할 수도 있지만 마찬가지이므로 간단하게 파일로 했습니다.
자바 프로그램이 데이터를 파일로 쓰고, C++ 프로그램이 그 파일을 읽는 것이지요.
C++ 프로그램은 위에서 말씀드린 여러 가지 이유로 운영 체제에 따라 수정할 필요가 있습니다.
제가 테스트한 운영체제는 솔라리스 2.6입니다.
- C++ 부분 소스 코드 : FileIOTest.C
- 자바 부분 소스 코드 : FileIOTest.java
컴파일 javac -encoding EUC_KR FileIOTest.java g++ -o tester FileIOTest.C 실행 java FileIOTest file.dat tester file.dat 실행 결과 다음 파일을 참조하세요... result.txt
댓글 없음:
댓글 쓰기