Ref : http://blogformatlab.blogspot.kr/2012/06/c.html
본 개시물은 매트랩에서 c로 만든 함수를 사용할 수 있는 방법을 모색하기 위한 단계의 들어가기이다.
본 개시물의 주된 목적은 이미 c로 만든 프로그램을 새로 매트랩으로 바꾸는 것이 아니라, 소량의 c프로그램 또는 함수를 수정해서 매트랩에서 바로 사용할 수 있도록 하려고 한다.
먼저
매트랩에서 새로운 편집 창을 열고, 비록 창이 비어있더라도 먼저 새로운 이름으로 저장하도록 한다. 이 때, 파일 형식은 All Files (*.*)을 선택한 후, 파일 이름으로 "Hello.c"라고 적고 저장 버튼을 누른다. 여기서 파일 이름의 확장자가 c임을 확인하도록 한다. 그러면 편집창의 모드는 더 이상 매트랩의 m-파일 형태가 아니라, c 프로그램 형태가 된다. 그리고 다음의 내용을 입력 또는 복사해서 붙여넣기를 하도록 한다.
#include "mex.h" /* Always include this */
void mexFunction(int nlhs, mxArray *plhs[], /* output variables */
int nrlh, const mxArray *prhsp[]) /* input variables */
{
mexPrintf("Hello, world!\n"); /* Do something interesting */
return;
}
**위 구문은 http://classes.soe.ucsc.edu/ee264/Fall11/cmex.pdf에서 발췌하였읍니다**
새로 입력한 구문의 내용은 간단히 매트랩 Command Window에 Hello, world! 라고 출력하는 것 뿐이다.
이제 Command Window에서 다음의 명령어를 입력하도록 한다.
mex Hello.c
그러면, 다음의 보기 항이 나올 것이다
Select a compiler:
[1] Lcc-win32 C 2.4.1 in D:\MATLAB\R2011b\sys\lcc
[2] Microsoft Visual C++ 6.0 in D:\Microsoft Visual Studio
[0] None
Compiler:
본 블로거의 컴퓨터에 이미 Visual C++가 설치되어 있기 때문에 2번을 Compiler 옆에 적고 Enter-키를 누르면 약간의 경고 메세지와 함께 다 되었다는 Done ...가 보이게 된다.
이제 Hello라고 명령어를 입력하면 마치 매트랩 m-파일 함수를 호출하는 것처럼 결과로 Hello, world!라 출력됨을 확인할 수 있다.
이제 위 예제를 통해 c프로그램을 매트랩에서 함수처럼 사용할 수 있는 것을 확인했으며 어떻게 c-프로그램 code를 매트랩의 함수로 변환시키는 지 방법도 확인하였다.
c-프로그램 모두 매트랩에서 사용될 수 있는 것은 아님을 눈치챘을 것 같으며, 사용되기 위해서는 몇 가지 지켜야할 규칙이 있다. 규칙들 중 몇 가지만 먼저 살펴보도록 하겠다.
1. 코드 맨 첫 줄에 mex.h를 include한다.
2. 코드의 함수는 main이 아니라 mexFunction이어야 한다. mexFunction 함수명의 인자는 4 개이며 각각은 다음의 의미를 지닌다.
nlhs : 실제 매트랩에서 함수를 사용할 때의 출력인자의 갯수
plhs: 실제 매트랩에서 함수를 사용할 때의 출력인자들
nrhs: 실제 매트랩에서 함수를 사용할 때의 입력인자의 갯수
prhs: 실제 매트랩에서 함수를 사용할 때의 입력인자들
3. mexPrintf 는 매트랩에서 fprintf와 동일한 효과를 나타낸다.
본 글과 보다 상세한 내용은 위의 링크를 따라가면 된다.
================================================================
================================================================
Ref : http://hopecus.tistory.com/3
MEX 는 MATLAB Executable 의 약자로 MATLAB 환경에서 실행가능한 C 함수를 작성할 수 있습니다. mexFunction 함수의 C 코드의 main함수와 같이 사용하고 mex compile을 이용하여 *.mexw32 (windows 32 bit 기준) 확장자를 갖는 MATLAB command, script, function에서 사용할 수 있는 실행함수를 구현할 수 있다.
함수의 기본틀은 다음과 같다. MATLAB 함수의 입력인자와 출력인자의 각각 개수와 이중포인터로 입력을 받는다.
#include "mex.h"
void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
}
nlhs : left-hand-side의 개수의 약자로 MATLAB함수의 출력 변수의 개수를 의미한다.
plhs : 출력 변수의 이중 포인터로 함수의 리턴값을 저장한다.
nrhs : right-hand-side의 개수의 약자로 MATLAB함수의 입력 변수의 개수를 의미한다.
prhs : 입력 변수의 이중 포인터로 함수의 입력값을 받는다.
다음은 입력 행렬값의 접근 방법과 출력 행렬을 위한 메모리 할당 및 값 설정에 대한 예제이다.
#include "mex.h"
void
mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
int i, j, k;
/* Input Arguments */
mexPrintf("\nThere are %d right-hand-side argument(s).", nrhs);
for (i=0; i<nrhs; i++) {
mexPrintf("\n\tInput Arg %i type=%s, dim=[%d %d]",i,mxGetClassName(prhs[i]),mxGetM(prhs[i]),mxGetN(prhs[i]));
mexPrintf("\n\t\t value=[");
for(j=0;j<mxGetM(prhs[i]);j++)
{
for(k=0;k<mxGetN(prhs[i]);k++)
mexPrintf("%lf ",mxGetPr(prhs[i])[k+j*mxGetN(prhs[i])]);
mexPrintf(";\n\t\t\t");
}
mexPrintf("]");
}
/* Output Arguments */
mexPrintf("\n\nThere are %d left-hand-side argument(s).\n", nlhs);
if (nlhs > nrhs)
mexErrMsgTxt("Cannot specify more outputs than inputs.\n");
for (i=0; i<nlhs; i++)
{
plhs[i]=mxCreateDoubleMatrix(mxGetM(prhs[i]),mxGetN(prhs[i]),mxREAL);
for(j=0;j<mxGetM(prhs[i]);j++)
{
for(k=0;k<mxGetN(prhs[i]);k++)
mxGetPr(plhs[i])[k+j*mxGetN(prhs[i])]=mxGetPr(prhs[i])[k+j*mxGetN(prhs[i])];
}
}
}
함수 mexGetM(prhs[i])는 i번째 입력 변수의 행의 개수와 mexGetN(prhs[i])는 열의 개수를 리턴한다. mexGetPr(prhs[i])는 i번째 입력 변수의 배열의 포인터를 얻을 수 있으며, mexGetPr(prhs[i])[j] 는 j번째 값을 접근할 수 있습니다. 2차원 배열인 경우 열이 우선순위가 있어 첫 번째 열부터 접근이 된다. 출력값은 mxCreateDoubleMatrix등과 같은 함수를 활용하여 메모리 할당한 후 값을 저장하면 됩니다.
디버깅을 위해서 메세지 출력은 mexPrintf() 함수를 사용합니다. mexFunction 함수 내의 printf() 함수도 동작하지만 mexFunction에서 call하는 subfuction내의 printf() 함수는 출력되지 않습니다. 따라서 mexPrintf() 사용하는 것이 좋습니다.
compiler는 처음에 한번 아래와 같이 설정합니다.
>>mex –setup
컴퓨터에 설치된 사용가능한 컴파일로 리스트가 표시되며, 사용자가 선택하면 됩니다.
컴파일은 다음과 같이 실행합니다.
>> mex mexEx1.c
주) 추가 c 파일이 있는 경우
>>mex mexEx1.c add01.c add02.c ..
와 같이 컴파일을 하며 같은 폴더에 없는 경우 c 파일의 전체경로 혹은 상대경로를 작성하면 되고 Include할 폴더는 –i 옵션을 사용하여 설정할 수 있습니다. 디버깅을 위해서는 -g 옵션을 사용하고 컴파일과정이나 warning message까지 확인하고 싶다면 -v 옵션을 사용합니다. -v
예제의 실행파일은 mexEx1.mexw32 와 같이 생성이 되며, OS환경에 따라서 확장자는 다를 수 있습니다.
실행은 다음과 같이하여 결과를 얻을 수 있습니다.
>> [A B]=mexEx1([1 2],[3 4 5;7 8 9])
There are 2 right-hand-side argument(s).
Input Arg 0 type=double, dim=[1 2]
value=[1.000000 2.000000 ;
]
Input Arg 1 type=double, dim=[2 3]
value=[3.000000 7.000000 4.000000 ;
8.000000 5.000000 9.000000 ;
]
There are 2 left-hand-side argument(s).
A =
1 2
B =
3 4 5
7 8 9