- Published on
Java에서 ocx 호출 삽질기 - 2부
- Authors
- Name
- Hyesung Lee
- GitHub
- @silentsoft
먼저 IPC와 RPC에 대해 간략히 짚어보고 삽질하기로 했다.
IPC (Inter-Process Communication)
- 서로 전혀 연관이 없는 프로세스간 통신을 하고자 할 때 사용한다.
- 종류 : 세마포어, 메세지 큐, 공유 메모리, 파이프(Named Pipe)
RPC (Remote Procedure Call)
- 로컬 혹은 원격지에서 실행되고 있는 프로세스의 함수를 마치 자기 프로그램에 있는 함수를 호출하는 것 처럼 사용하고자 할 때 사용한다.
- 종류 : WMI, RMI, CORBA
IPC와 RPC를 고민하던 중, 원격지의 프로세스도 호출할 수 있는 RPC가 더 끌렸다.
나중에 Client(Java)와 Server(C++)가 분리되어 다른 컴퓨터에 실행되더라도
사용할 수 있다는 확장성과, 마치 내 프로그램인냥 함수 호출과 같은 형태로 데이터를 끌어올 수 있다는 점에서 RPC부터 삽질하기로 했다.
만약, Client와 Server가 둘 다 Java라면 RMI를 이용하는 편이 훨씬 정신건강에 이롭다. 내가 해야하는 것은 Java에서 C++(exe) 함수 호출이니, RMI는 접어두고…
RPC의 종류 중 하나인 CORBA (Common Object Request Broker Architecture)는 서로 다른 언어로 작성 된 프로세스에서 원격 함수를 호출하기에 적합하게 고안되었고, 표준으로 자리잡혀있다. 서로 다른 언어로 작성되다보니 중간 프로토콜을 협의해야 하는데, 이것이 IDL (Interface Description Language)이다.
CORBA 사용 방법에 들어가기에 앞서, Client와 Server의 용어 정의는 이렇다.
Client는 원격지 프로세스의 함수를 호출하는 호출자이고, Server는 호출당하는 수신자이다.
Stub과 Skeleton에 대한 용어는 설명할 필요 없으므로 생략..
Client가 Java이고, Server가 C++인 경우, CORBA를 쓰기 위한 절차는 아래와 같다.
Java에서 사용하기 위한 인터페이스인 IDL 파일을 작성 후 idlj 컴파일러로 컴파일.
C++에서 사용하기 위한 인터페이스인 IDL 파일을 작성 후 idl 컴파일러로 컴파일.
C++에서 포트와 서비스 네임을 정의한 후 인터페이스 바인딩.
Java에서 호출 할 원격지의 호스트와 포트, 서비스 네임을 기준으로 호출.
Java에서는 idlj 컴파일러가 JDK 1.7부터 내장되었기에 비교적 무난하게 수행할 수 있다.
문제는 C++인데, 알아보니 IDL 컴파일러가 죄다 리눅스용이다.. (대략난감…)
그래서, 엄청난 시간을 투자해서 방법을 알아보던 중 그냥 포기하기로 했다.
(뭔가 패배한 기분이지만 그래도 아직 IPC가 있기에..)
IPC는 네트워크를 거치지 않고, OS 영역을 경유하여 프로세스간 통신하는 방법이다.
운영체제를 공부하다 보면 꼭 거치는 3대 천왕이 여기 세마포어, 메세지 큐, 공유 메모리이다. 어떤걸로 선택할까 고민하다가 생소한 파이프 통신을 해보기로 했다.
파이프의 통신의 개념은 정말 간단하다. 어디서든 택배를 주고받을 수 있는 마법의 문이 있다고 가정하자. Server(C++)가 만들어 놓은 마법의 문으로 Client(Java)에서 데이터를 던진다. Server에서는 Client가 방금 던진 그 데이터를 바로 코 앞에서 받아볼 수 있다. 예를 들면 그렇다는 말이다.
Named Pipe 통신은 이름에서 유추할 수 있듯이, Server와 Client가 마법의 문을 통해서 택배를 주고 받기 위해서는 주소(Name)가 필요하다.
바로 이 명명된 파이프를 통해서 데이터를 주고 받는데, 코드가 너무 간단하다. 테스트 해본 결과 이상없이 잘 동작한다. 너무나도 간단하게 말이다. (Named Pipe를 통한 구현 코드는 검색하면 바로 나오는 부분이므로 생략)
지금까지의 삽질을 정리하자면,
x64 프로세스에서는 죽었다 깨어나도 x86 머신에서 컴파일 된 COM 오브젝트를 못쓴다.
그러나 x64 머신 또는 프로세스에서는 x86 머신에서 컴파일 된 exe를 실행할 수 있다.
x64 머신 또는 프로세스에서 x86 프로세스(exe)를 실행하고, x86 프로세스에서 x86 COM 오브젝트를 로딩한 뒤, IPC 통신을 통하여 요청이 들어올 때 Java(x64 JVM)로 전달한다.