खोज…


C ++ MEX- फ़ाइल में इनपुट / आउटपुट की संख्या की जाँच करें

इस उदाहरण में हम एक मूल कार्यक्रम लिखेंगे जो एमईएक्स-फ़ंक्शन को दिए गए इनपुट और आउटपुट की संख्या की जांच करता है।

शुरुआती बिंदु के रूप में, हमें "एमईएक्स गेटवे" को लागू करने वाली सी ++ फ़ाइल बनाने की आवश्यकता है। यह तब निष्पादित किया जाता है जब फ़ाइल 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.h हेडर जिसमें एमएक्स एपीआई के साथ काम करने के लिए सभी आवश्यक फ़ंक्शन और डेटा प्रकार की परिभाषाएं हैं। फिर हम फंक्शन mexFunction को लागू करते हैं, mexFunction कि दिखाया गया है, जहां इसके हस्ताक्षर को नहीं बदलना चाहिए, वास्तव में उपयोग किए जाने वाले इनपुट / आउटपुट से स्वतंत्र। फ़ंक्शन पैरामीटर निम्नानुसार हैं:

  • nlhs : अनुरोधित आउटपुट की संख्या।
  • *plhs[] : MEX एपीआई प्रारूप में सभी आउटपुट युक्त सरणी।
  • nrhs : इनपुट की संख्या पारित की गई।
  • *prhs[] : सरणी जिसमें MEX API प्रारूप में सभी इनपुट हैं।

अगला, हम इनपुट / आउटपुट तर्कों की संख्या की जांच करते हैं, और यदि सत्यापन विफल हो जाता है, तो एक त्रुटि mexErrMsgIdAndTxt फ़ंक्शन का उपयोग करके फेंक दी mexErrMsgIdAndTxt है (यह somename:iD उम्मीद somename: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 में स्ट्रिंग हेरफेर का वर्णन करते हैं। हम एक MEX- फ़ंक्शन बनाएंगे जो MATLAB से इनपुट के रूप में एक स्ट्रिंग को स्वीकार करता है, डेटा को C-string में कॉपी करता है, इसे संशोधित करता है और इसे वापस mxArray परिवर्तित करता है MATLAB की तरफ।

इस उदाहरण का मुख्य उद्देश्य यह दिखाना है कि कैसे MATLAB से तार को 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 अगर एक परीक्षण करने के लिए mxArray की है mxCHAR प्रकार।
  • mxArrayToString एक mxArray स्ट्रिंग के डेटा को char * बफ़र पर कॉपी करने के लिए।
  • mxCreateString एक char* से mxArray स्ट्रिंग बनाने के लिए।

एक साइड नोट के रूप में, यदि आप केवल स्ट्रिंग को पढ़ना चाहते हैं, और इसे संशोधित नहीं करना चाहते हैं, तो गति और मजबूती के लिए इसे const char* घोषित करना याद रखें।


अंत में, एक बार संकलित करने के बाद हम इसे MATLAB से कह सकते हैं:

>> mex stringIO.cpp

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

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

MATLAB से C तक 3D मैट्रिक्स पास करें

इस उदाहरण में हम बताते हैं कि 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 मैट्रिसेस सभी 1D मेमोरी में हैं, भले ही MATLAB में कितने आयाम हों। यह अधिकांश (यदि सभी नहीं है) C / C ++ पुस्तकालयों में मुख्य मैट्रिक्स प्रतिनिधित्व के लिए भी सही है, क्योंकि अनुकूलन और तीव्र निष्पादन की अनुमति देता है।

  • आपको MATLAB से C तक लूप में स्पष्ट रूप से मैट्रिसेस कॉपी करने की आवश्यकता है।

  • MATLAB मैट्रिस को स्तंभ प्रमुख क्रम में, जैसे कि फोरट्रान में संग्रहीत किया जाता है, लेकिन C / C ++ और अधिकांश आधुनिक भाषाएँ पंक्ति प्रमुख हैं। इनपुट मैट्रिक्स को अनुमति देना महत्वपूर्ण है, अन्यथा डेटा पूरी तरह से अलग दिखाई देगा।

इस उदाहरण में प्रासंगिक कार्य हैं:

  • यदि इनपुट double टाइप है तो mxIsDouble चेक करता है।
  • mxIsComplex जाँच करता है कि इनपुट वास्तविक है या काल्पनिक है।
  • mxGetData इनपुट सरणी में वास्तविक डेटा के लिए एक पॉइंटर लौटाता है। वास्तविक डेटा न होने पर NULL
  • mxGetDimensions प्रत्येक इंडेक्स में आयाम के आकार के साथ एक mwSize सरणी के लिए एक पॉइंटर लौटाता है।

फ़ील्ड नामों से एक संरचना पास करना

यह उदाहरण दिखाता है कि MATLAB से विभिन्न प्रकार की संरचना प्रविष्टियों को कैसे पढ़ें, और इसे 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);
    }
  }
}

दिए गए if(0==strcmp) में i प्रत्येक क्षेत्र पर लूप चलाता i , जबकि if(0==strcmp) -पार्ट्स दिए गए स्ट्रिंग के लिए मैटलैब फील्ड के नाम की तुलना करते हैं। यदि यह एक मिलान है, तो संबंधित मान C चर में निकाला जाता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow