MATLAB Language
MEX API 소개
수색…
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);
}
이 예제의 관련 함수는 다음과 같습니다.
-
mxIsChar
가mxCHAR
유형인지 테스트하려면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
는 입력이double
형mxIsDouble
확인합니다. -
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 변수에 추출됩니다.