Matlab 코드를 단일실행파일로 만들거나 C/C++ 또는 Java 라이브러리로 만들어서 배포할 수 있다.
우선 Matlab에서 컴파일러를 설정해야 하는데, 이건 인터넷 뒤져서 하기 바란다. matlab 커맨드 윈도우에서 mbuild -setup이라고치면 뭔가 나오는데 거기서 적당한 컴파일러 선택하면 된다. 리눅스에서는 gcc를 선택하면 되겠다.
그럼 컴파일러 설정이 다 되어있다는 가정하에 리눅스 환경에서 C 공유라이브러리 생성을 해보자. 우선 아래와 같이 이미지의 히스토그램을 구해서 화면에 출력하는 간단한 matlab 코드를 만들고 foo.m으로 저장한다. 입력 파라메터 filename은 이미지 파일명, 츨력 파라메터 H는 구해진 히스토그램이다.
more..
function H = foo(filename)
I = imread(filename);
G = rgb2gray(I);
H = imhist(G, 256);
end
이제 아래와 같이 순서대로 따라한다.
1. matlab 커맨드 윈도우에서 deploytool이라고 치면 GUI 창이 나온다.
2. 새로운 프로젝트 생성 아이콘을 눌러서 C Shared Library를 선택
3. 프로젝트 이름을 libfoo.prj로 해서 생성
4. Exported functions를 오른쪽 클릭하고 Add를 눌러서 foo.m 파일을 등록한다.
5. Build 버튼을 눌러서 컴파일 한다. 당연 에러가 발생하면 안되고 성공적으로 끝났다는 메시지가 나와야 한다.
5. Package 버튼을 눌러서 컴파일된 파일들을 패키징한다.
6. 패키징된 파일은 ZIP 파일이다. 압축을 풀면 MCRInstaller.bin 파일과 컴파일 결과물이 있는데, MCRInstaller.bin을 실행해서 Matlab Compiler Runtime을 시스템에 설치한다. 설치 전에 bc가 미리 설치되어 있어야하고, 그래픽 환경이 아닌 경우에는 인스톨러를 실행할 때 -console 옵션을 주고 실행해야 콘솔에서 설치가 가능하다. 설치 과정은 반응도 느리고 좀 답답하니 참고하기 바란다. 그리고 X 관련 라이브러리가 설치되지 않은 시스템에서는 나중에 C 코드를 컴파일해서 실행할 때 라이브러리를 못찾는 에러가 나온다. 따라서 미리 아래 라이브러리들을 설치해준다.
$ sudo apt-get install libxt6 libxt-dev libxpm4 libxpm-dev libxmu6 libxmu-dev libxp6 libxp-dev
7. libfoo 라이브러리를 호출하는 C 소스코드를 만들고 컴파일 한다. 코드는 아래에 있는걸 사용하면 된다. 컴파일 과정에서 LIB_PREFIX에는 Matlab Compiler Runtime을 설치한 경로를 입력하면 된다. 참고로 현재 디렉토리는 패키지를 풀어놓은 디렉토리이다.
more..
$ export LIB_PREFIX=/usr/local/matlab/runtime
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIB_PREFIX/v79/runtime/glnxa64:.
$ gcc -Wall -o foo -I$LIB_PREFIX/v79/extern/include foo.c -L. -lfoo
$ ./foo /data/images/object_01.jpg
11893
14881
17332
15898
13204
... (생략)
아래는 테스트용 C 소스코드이다.
more..
#include <stdio.h>
#include "libfoo.h" /* MATLAB-generated header file */
int main(int argc, char **argv)
{
mxArray *x_ptr;
mxArray *y_ptr=NULL;
double *y;
size_t len;
int i;
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Call the MCR and library initialization functions */
if( !mclInitializeApplication(NULL,0) )
{
fprintf(stderr, "Could not initialize the application.\n");
exit(1);
}
if (!libfooInitialize())
{
fprintf(stderr,"Could not initialize the library.\n");
exit(1);
}
/* Create an mxArray to input into mlfFoo */
x_ptr = mxCreateString(argv[1]);
/* Call the implementation function */
/* Note the second input argument should be &y_ptr instead of y_ptr. */
if (!mlfFoo(1,&y_ptr,x_ptr)) {
fprintf(stderr, "Fail..\n");
exit(1);
}
/* The return value from mlfFoo is an mxArray. Use mxGetpr to get a pointer to data it contains. */
y = mxGetPr(y_ptr);
len = mxGetM(y_ptr);
for (i = 0; i < len; i++)
/* Display the output of the call to mlfFoo. */
printf("%d\n", (int) y[i]);
mxDestroyArray(x_ptr);
/* Call the library termination function */
libfooTerminate();
mclTerminateApplication();
return 0;
}
C 코드에서 shared library function에 파라메터를 주고 받을 때 사용하는 API는
여기를 참조한다.
참고로 MATLAB 컴파일러가 만드는 공유라이브러리 코드는 출력과 에러를 각각 stdout, stderr로 보낸다. 만약 이걸 다르게 처리하고 싶다면 출력, 에러 핸들러를 각각 만들어서 라이브러리를 초기화를 할 때 <lib>Initializer() 함수 대신 <lib>InitializerWithHandlers() 함수를 사용해서 등록해준다. 자세한 내용은
여기를 참조한다. 그리고 함수의 출력인자가 여러 개인 경우도 설명되어 있으니 참조한다.
그리고 C 코드에서 반드시 MCR과 shared library를 초기화하고 제거하는 코드가 아래와 같이 들어가야 한다. <lib>는 방금 만든 shared library의 이름으로 대체하면 된다. 참고로 matlab에서 나오는 모든 스칼라 값은 double 타입으로 넘어온다.
...code...
mclInitializeApplication();
<lib>Initialize();
...code...
<lib>Terminate();
mclTerminateApplication();
...code...
trackbacks
http://superkkt.com/trackback/434
-
Tracked from "행복한 프로그래머"
2010/02/05 18:56
D
매틀랩과 C 혹은 C++ 과 연결하는 방법에 대해서 이미 다른 블로거 분들이 올렸는데, 실질적으로 .NET 라이브러리화되어서 연동시켜서 매틀랩의 함수들을 사용하는 방식에 대해서는 안 나와 있어서 이렇게 올리게 되었습니다. 일단. 아래의 링크에 가셔서 기본적인 절차를 숙지 하셔야 합니다. Matlab에서 C++ DLL 만들어보세~ Matlab Builder NE를 이용하라!! ????.NET용 DLL을 만들어서 C#과 연결하기 위해서는 아래화면에서 M..
comments
comments rss (+댓글 쓰러가기)