수색…


C ++ MEX 파일에서 입출력 수를 확인하십시오.

이 예에서는 MEX 기능으로 전달되는 입력 및 출력의 수를 확인하는 기본 프로그램을 작성합니다.

출발점으로 "MEX 게이트웨이"를 구현하는 C ++ 파일을 만들어야합니다. 이것은 MATLAB에서 파일을 호출 할 때 실행되는 함수입니다.

testinputs.cpp

// MathWorks provided header file
#include "mex.h"

// gateway function
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // This function will error if number of inputs its not 3 or 4
    // This function will error if number of outputs is more than 1

    // Check inputs:
    if (nrhs < 3 || nrhs > 4) {
        mexErrMsgIdAndTxt("Testinputs:ErrorIdIn",
            "Invalid number of inputs to MEX file.");
    }

    // Check outputs:
    if (nlhs > 1) {
        mexErrMsgIdAndTxt("Testinputs:ErrorIdOut",
                "Invalid number of outputs to MEX file.");
    }
}

먼저, MEX API를 사용하기 위해 필요한 모든 함수 및 데이터 유형의 정의가 들어있는 mex.h 헤더를 포함합니다. 그런 다음 실제로 표시된 입력 / 출력에 관계없이 서명을 변경해서는 mexFunction 함수를 구현합니다. 함수 매개 변수는 다음과 같습니다.

  • nlhs : 요청 된 출력 수.
  • *plhs[] : MEX API 형식의 모든 출력을 포함하는 배열입니다.
  • nrhs : 전달 된 입력의 수.
  • *prhs[] : MEX API 형식의 모든 입력을 포함하는 배열입니다.

다음에는 입력 / 출력의 인수의 수를 확인하고, 검증이 실패하면, 에러가 사용 슬로우 mexErrMsgIdAndTxt 함수 (이것은 기대 somename:iD 포맷 식별자, 간단한 "ID"가 작동하지 않을 것이다).


파일이 mex testinputs.cpp 로 컴파일되면 MATLAB에서 함수를 다음과 같이 호출 할 수 있습니다.

>> testinputs(2,3)
Error using testinputs. Invalid number of inputs to MEX file.

>> testinputs(2,3,5)

>> [~,~] = testinputs(2,3,3)
Error using testinputs. Invalid number of outputs to MEX file.

문자열을 입력하고 C로 수정 한 다음 출력하십시오.

이 예에서는 MATLAB MEX에서 문자열 조작을 보여줍니다. MATLAB에서 문자열을 입력으로 받아들이고 데이터를 C- 문자열로 복사하고 수정 한 다음 다시 mxArray 로 변환하여 MATLAB 측으로 반환하는 MEX 함수를 만듭니다.

이 예제의 주요 목적은 MATLAB에서 문자열을 C / C ++로 변환하는 방법과 그 반대로 문자열을 C / C ++로 변환하는 방법을 보여주는 것입니다.

stringIO.cpp

#include "mex.h"
#include <cstring>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // check number of arguments
    if (nrhs != 1 || nlhs > 1) {
        mexErrMsgIdAndTxt("StringIO:WrongNumArgs", "Wrong number of arguments.");
    }

    // check if input is a string
    if (mxIsChar(prhs[0])) {
        mexErrMsgIdAndTxt("StringIO:TypeError", "Input is not a string");
    }

    // copy characters data from mxArray to a C-style string (null-terminated)
    char *str = mxArrayToString(prhs[0]);

    // manipulate the string in some way
    if (strcmp("theOneString", str) == 0) {
        str[0] = 'T';  // capitalize first letter
    } else {
        str[0] = ' ';  // do something else?
    }

    // return the new modified string
    plhs[0] = mxCreateString(str);

    // free allocated memory
    mxFree(str);
}

이 예제의 관련 함수는 다음과 같습니다.

  • mxIsCharmxCHAR 유형인지 테스트하려면 mxArray .
  • mxArrayToString (A)의 데이터 복사 mxArray (A)에 문자열을 char * 버퍼.
  • mxCreateString 을 사용하여 char* 에서 mxArray 문자열을 만듭니다.

부수적으로 문자열을 읽고 수정하지 않으려는 경우에는 속도와 견고성을 위해 const char* 로 선언해야합니다.


마지막으로 컴파일이 끝나면 MATLAB에서 다음과 같이 호출 할 수 있습니다.

>> mex stringIO.cpp

>> strOut = stringIO('theOneString')
strOut = 
TheOneString

>> strOut = stringIO('somethingelse')
strOut=
omethingelse

MATLAB에서 3D 행렬을 C로 전달

이 예제에서는 MATLAB에서 이중 실수 형 3D 행렬을 가져 와서 C double* 배열로 전달하는 방법을 보여줍니다.

이 예제의 주요 목적은 MATLAB MEX 배열에서 데이터를 얻는 방법과 매트릭스 저장 및 처리에 대한 세부 사항을 강조하는 방법을 보여줍니다.

matrixIn.cpp

#include "mex.h"

void mexFunction(int  nlhs , mxArray *plhs[],
        int nrhs, mxArray const *prhs[]){
   // check amount of inputs
   if (nrhs!=1) {
        mexErrMsgIdAndTxt("matrixIn:InvalidInput", "Invalid number of inputs to MEX file.");
    }
   
   // check type of input
   if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])){
        mexErrMsgIdAndTxt("matrixIn:InvalidType",  "Input matrix must be a double, non-complex array.");
   }
   
   // extract the data
   double const * const matrixAux= static_cast<double const *>(mxGetData(prhs[0]));

   // Get matrix size
   const mwSize *sizeInputMatrix= mxGetDimensions(prhs[0]);

   // allocate array in C. Note: its 1D array, not 3D even if our input is 3D
   double*  matrixInC= (double*)malloc(sizeInputMatrix[0] *sizeInputMatrix[1] *sizeInputMatrix[2]* sizeof(double));

  
   // MATLAB is column major, not row major (as C). We need to reorder the numbers
   // Basically permutes dimensions   

   // NOTE: the ordering of the loops is optimized for fastest memory access! 
   // This improves the speed in about 300% 

    const int size0 = sizeInputMatrix[0]; // Const makes compiler optimization kick in
    const int size1 = sizeInputMatrix[1];
    const int size2 = sizeInputMatrix[2];
    
    for (int j = 0; j < size2; j++)
    {
        int jOffset = j*size0*size1; // this saves re-computation time
        for (int k = 0; k < size0; k++)
        {
            int kOffset = k*size1; // this saves re-computation time
            for (int i = 0; i < size1; i++)
            {
                int iOffset = i*size0; 
                matrixInC[i + jOffset + kOffset] = matrixAux[iOffset + jOffset + k];
            }
        }
    }

    // we are done!

    // Use your C matrix here

    // free memory
    free(matrixInC);
    return;
}

관련 개념 :

  • MATLAB 행렬은 MATLAB에서 사용될 때 얼마나 많은 차원을 가지고 있더라도 메모리에 모두 1D입니다. 이것은 C / C ++ 라이브러리의 대부분의 (전부는 아닐지라도) 주 매트릭스 표현에서도 마찬가지입니다. 최적화와 빠른 실행이 가능합니다.

  • 루프의 MATLAB에서 C로 행렬을 명시 적으로 복사해야합니다.

  • MATLAB 행렬은 Fortran에서와 같이 열 주요 순서로 저장되지만 C / C ++ 및 대부분의 현대 언어는 행 주요입니다. 입력 행렬을 바꾸는 것이 중요합니다. 그렇지 않으면 데이터가 완전히 다르게 보입니다.

이 예제의 관련 함수는 다음과 같습니다.

  • mxIsDouble 는 입력이 doublemxIsDouble 확인합니다.
  • mxIsComplex 는 입력이 실수인지 mxIsComplex 검사합니다.
  • mxGetData 는 입력 배열의 실제 데이터에 대한 포인터를 반환합니다. 실제 데이터가 없으면 NULL 입니다.
  • mxGetDimensions 는 각 인덱스의 크기 크기와 함께 mwSize 배열에 대한 포인터를 반환합니다.

구조체를 필드 이름으로 전달

이 예제는 MATLAB에서 다양한 유형의 구조체 항목을 읽고 C 유형의 변수에 전달하는 방법을 보여줍니다.

이 예제에서는 숫자로 필드를로드하는 방법을 쉽게 이해할 수 있지만 여기에서는 필드 이름과 문자열을 비교하여이를 수행합니다. 따라서 struct 필드는 필드 이름으로 처리 할 수 ​​있으며 변수는 C로 읽을 수 있습니다.

structIn.c

#include "mex.h"
#include <string.h> // strcmp


void mexFunction (int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
  // helpers
  double* double_ptr;
  unsigned int i; // loop variable
  
  // to be read variables
  bool optimal;
  int randomseed;
  unsigned int desiredNodes;

  if (!mxIsStruct(prhs[0])) {
    mexErrMsgTxt("First argument has to be a parameter struct!");
  }
  for (i=0; i<mxGetNumberOfFields(prhs[0]); i++) {
    if (0==strcmp(mxGetFieldNameByNumber(prhs[0],i),"randomseed")) {
      mxArray *p = mxGetFieldByNumber(prhs[0],0,i);
      randomseed = *mxGetPr(p);
    }
    if (0==strcmp(mxGetFieldNameByNumber(prhs[0],i),"optimal")) {
      mxArray *p = mxGetFieldByNumber(prhs[0],0,i);
      optimal = (bool)*mxGetPr(p);
    }
    if (0==strcmp(mxGetFieldNameByNumber(prhs[0],i),"numNodes")) {
      mxArray *p = mxGetFieldByNumber(prhs[0],0,i);
      desiredNodes = *mxGetPr(p);
    }
  }
}

이상 루프 i 그동안 주어진 구조체의 모든 분야에 걸쳐 실행되는 if(0==strcmp) 주어진 문자열로 MATLAB 필드의 이름을 비교 -parts. 일치하는 경우 해당 값이 C 변수에 추출됩니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow