Main Content

C 소스 MEX 파일 arrayProduct.c 만들기

이 예제에서는 C Matrix API에 정의된 MATLAB® 배열을 사용하여 MATLAB에서 C 함수 arrayProduct를 호출하는 MEX 파일을 작성하는 방법을 보여줍니다. 여기에서 전체 소스 파일을 볼 수 있습니다.

이 예제를 사용하기 위한 전제 조건은 다음과 같습니다.

  • C 또는 C++ 소스 코드를 작성할 수 있어야 함. 이 파일은 사용자가 MATLAB 편집기에서 생성합니다.

  • MATLAB에서 지원되는 컴파일러. 지원되는 컴파일러의 최신 목록을 보려면 지원 및 호환되는 컴파일러 웹사이트를 참조하십시오.

  • C Matrix APIC MEX API의 함수.

  • mex 빌드 스크립트.

자신만의 고유한 C 개발 환경을 사용하려는 경우 자세한 내용은 MEX 스크립트 옵션을 사용한 사용자 지정 빌드 항목을 참조하십시오.

C 함수 arrayProduct

다음 코드는 1xn 행렬 y에 스칼라 값 x를 곱한 다음 결과값을 배열 z로 반환하는 arrayProduct 함수를 정의합니다. 이와 동일한 C 명령문을 C++ 애플리케이션에서도 사용할 수 있습니다.

void arrayProduct(double x, double *y, double *z, int n)
{
  int i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

소스 파일 만들기

MATLAB 편집기를 열고 파일을 만든 후 다음 정보를 MEX 파일에 기록합니다.

/*
 * arrayProduct.c - example in MATLAB External Interfaces
 *
 * Multiplies an input scalar (multiplier) 
 * times a 1xN matrix (inMatrix)
 * and outputs a 1xN matrix (outMatrix)
 *
 * The calling syntax is:
 *
 *		outMatrix = arrayProduct(multiplier, inMatrix)
 *
 * This is a MEX file for MATLAB.
*/

MATLAB API 함수 선언이 포함된 C/C++ 헤더 파일 mex.h를 추가합니다.

#include "mex.h"

파일을 MATLAB 경로(예: c:\work 내)에 저장하고 이름을 arrayProduct.c로 지정합니다. 작성한 MEX 파일의 이름은 arrayProduct입니다.

게이트웨이 루틴 만들기

모든 C 프로그램에는 main() 함수가 포함되어 있습니다. MATLAB은 게이트웨이 루틴 mexFunction을 함수에 대한 진입점으로 사용합니다. 다음 mexFunction 코드를 추가하십시오.

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
/* variable declarations here */

/* code here */
}

다음 표에는 mexFunction의 입력 파라미터가 설명되어 있습니다.

파라미터설명
nlhs출력(왼쪽) 인수의 개수 또는 plhs 배열의 크기입니다.
plhs출력 인수로 구성된 배열입니다.
nrhs입력(오른쪽) 인수의 개수 또는 prhs 배열의 크기입니다.
prhs입력 인수로 구성된 배열입니다.

MEX 파일의 입력 파라미터와 출력 파라미터 확인하기

nrhs 인수와 nlhs 인수를 사용하여 MEX 파일의 입력 인수와 출력 인수 개수를 확인합니다.

두 개의 입력 인수 multiplierinMatrix가 있는지 확인하려면 다음 코드를 사용하십시오.

if(nrhs != 2) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",
                      "Two inputs required.");
}

배열의 곱을 의미하는 출력 인수 outMatrix가 있는지 확인하려면 다음 코드를 사용하십시오.

if(nlhs != 1) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",
                      "One output required.");
}

plhs 인수와 prhs 인수를 사용하여 인수 유형을 확인합니다. 다음 코드는 prhs[0]으로 나타낸 multiplier가 스칼라인지 확인합니다.

/* make sure the first input argument is scalar */
if( !mxIsDouble(prhs[0]) || 
     mxIsComplex(prhs[0]) ||
     mxGetNumberOfElements(prhs[0]) != 1 ) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar",
                      "Input multiplier must be a scalar.");
}

다음 코드는 prhs[1]로 나타낸 inMatrixdouble형인지 확인합니다.

if( !mxIsDouble(prhs[1]) || 
     mxIsComplex(prhs[1])) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble",
        "Input matrix must be type double.");
}

inMatrix가 행 벡터인지 확인합니다.

/* check that number of rows in second input argument is 1 */
if(mxGetM(prhs[1]) != 1) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",
                      "Input must be a row vector.");
}

계산 루틴 만들기

arrayProduct 코드를 추가합니다. 이 함수는 계산 루틴, 즉 MATLAB에서 사용하고자 하는 기능을 수행하는 소스 코드입니다.

void arrayProduct(double x, double *y, double *z, int n)
{
  int i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

계산 루틴은 선택 사항입니다. 또는, 이 코드를 mexFunction 함수 블록 내에 넣을 수 있습니다.

크로스 플랫폼 유연성을 염두에 둔 코드 작성하기

MATLAB은 플랫폼에 따라 정수의 크기 값을 나타내는 전처리기 매크로 mwsize를 제공합니다. 계산 루틴은 배열의 크기를 int로 선언합니다. 변수 ni에 대한 int 선언을 mwsize로 바꾸십시오.

void arrayProduct(double x, double *y, double *z, mwSize n)
{
  mwSize i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

계산 루틴의 변수 선언하기

mexFunction에 다음 변수 선언을 넣으십시오.

  • 입력 인수에 대한 변수를 선언합니다.

    double multiplier;      /* input scalar */
    double *inMatrix;       /* 1xN input matrix */
    
  • 입력 행렬의 크기에 대해 ncols를 선언합니다.

    mwSize ncols;           /* size of matrix */
    
  • 출력 인수 outMatrix를 선언합니다.

    double *outMatrix;      /* output matrix */
    

나중에 이러한 변수에 mexFunction 인수를 할당합니다.

입력 데이터 읽어오기

스칼라 입력값을 읽어오려면 mxGetScalar 함수를 사용하십시오.

/* get the value of the scalar input  */
multiplier = mxGetScalar(prhs[0]);

mxGetDoubles 함수를 사용하여 입력 행렬 데이터를 가리킵니다.

/* create a pointer to the real data in the input matrix  */
inMatrix = mxGetDoubles(prhs[1]);

mxGetN 함수를 사용하여 행렬의 크기를 가져옵니다.

/* get dimensions of the input matrix */
ncols = mxGetN(prhs[1]);

출력 데이터 준비하기

출력 인수 plhs[0]을 만들려면 mxCreateDoubleMatrix 함수를 사용하십시오.

/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);

mxGetDoubles 함수를 사용하여 outMatrix 인수를 plhs[0]에 할당합니다.

/* get a pointer to the real data in the output matrix */
outMatrix = mxGetDoubles(plhs[0]);

계산 수행하기

인수를 arrayProduct에 전달합니다.

/* call the computational routine */
arrayProduct(multiplier,inMatrix,outMatrix,ncols);

완성된 소스 파일 보기

작성한 소스 파일을 matlabroot/extern/examples/mex에 있는 arrayProduct.c와 비교해 보십시오. 편집기에서 파일 arrayProduct.c를 엽니다.

C++용 MATLAB Data API를 사용하는 C++ MEX 파일 예제는 arrayProduct.cpp를 참조하십시오. 이 API를 사용하여 MEX 파일을 만드는 방법에 대한 자세한 내용은 C++ MEX 함수 항목을 참조하십시오.

MEX 함수 빌드하기

MATLAB 명령 프롬프트에서 mex 명령을 사용하여 함수를 빌드합니다.

mex arrayProduct.c -R2018a

MEX 함수 테스트하기

s = 5; 
A = [1.5, 2, 9];
B = arrayProduct(s,A)
B =
    7.5000   10.0000   45.0000 

MEX 파일의 입력 인수 확인하기

MEX 함수를 호출하기 전에 MATLAB 변수의 유형을 확인하는 것이 좋습니다. 입력 변수 inputArg를 테스트하고 필요한 경우 double형으로 변환하려면 다음 코드를 사용하십시오.

s = 5; 
A = [1.5, 2, 9];
inputArg = int16(A);
if ~strcmp(class(inputArg),'double')
    inputArg = double(inputArg);
end
B = arrayProduct(s,inputArg)

참고 항목

| |

관련 항목