Mex type C file to обычный C file - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть c файл, написанный с использованием mex-функций, который запускается Matlab с помощью mex-компилятора. Теперь я хочу запустить эти mex type. c файлы без среды Matlab. Итак, есть ли способ конвертировать mex type. c file в normal. c file? Или любые другие варианты, доступные для вышеупомянутого беспокойства. Заранее спасибо ....!

Вот один мекс тип. c файл для образца.

#include <stdlib.h>
#include "mex.h"
#include "matrix.h"
#include "distances.h"
#include "ltl2tree.h"
#include "param.h"


#define BUFF_LEN 4096

char * emalloc(size_t n)
{       
    char *tmp;

    if (!(tmp = (char *) mxMalloc(n)))
        mexErrMsgTxt("mx_dp_taliro: not enough memory!");
    memset(tmp, 0, n);
    return tmp;
}

int tl_Getchar(int *cnt, size_t hasuform, char *uform)
{
    if (*cnt < hasuform)
        return uform[(*cnt)++];
    (*cnt)++;
    return -1;
}

void tl_UnGetchar(int *cnt)
{
    if (*cnt > 0) (*cnt)--;
}

#define Binop(a)        \
        fprintf(miscell->tl_out, "(");  \
        dump(n->lft, miscell);      \
        fprintf(miscell->tl_out, a);    \
        dump(n->rgt, miscell);      \
        fprintf(miscell->tl_out, ")")

static void sdump(Node *n, char *dumpbuf)
{
    switch (n->ntyp) {
    case PREDICATE: strcat(dumpbuf, n->sym->name);
            break;
    case U_OPER:    strcat(dumpbuf, "U");
            goto common2;
    case V_OPER:    strcat(dumpbuf, "V");
            goto common2;
    case OR:    strcat(dumpbuf, "|");
            goto common2;
    case AND:   strcat(dumpbuf, "&");
common2:        sdump(n->rgt,dumpbuf);
common1:        sdump(n->lft,dumpbuf);
            break;
    case NEXT:  strcat(dumpbuf, "X");
            goto common1;
    case NOT:   strcat(dumpbuf, "!");
            goto common1;
    case TRUE:  strcat(dumpbuf, "T");
            break;
    case FALSE: strcat(dumpbuf, "F");
            break;
    default:    strcat(dumpbuf, "?");
            break;
    }
}

Symbol *DoDump(Node *n, char *dumpbuf, Miscellaneous *miscell)
{
    if (!n) return ZS;

    if (n->ntyp == PREDICATE)
        return n->sym;

    dumpbuf[0] = '\0';
    sdump(n,dumpbuf);
    return tl_lookup(dumpbuf, miscell);
}

void dump(Node *n, Miscellaneous *miscell)
{
    if (!n) return;

    switch(n->ntyp) {
    case OR:    Binop(" || "); break;
    case AND:   Binop(" && "); break;
    case U_OPER:    Binop(" U ");  break;
    case V_OPER:    Binop(" V ");  break;
    case NEXT:
        fprintf(miscell->tl_out, "X");
        fprintf(miscell->tl_out, " (");
        dump(n->lft, miscell);
        fprintf(miscell->tl_out, ")");
        break;
    case NOT:
        fprintf(miscell->tl_out, "!");
        fprintf(miscell->tl_out, " (");
        dump(n->lft, miscell);
        fprintf(miscell->tl_out, ")");
        break;
    case FALSE:
        fprintf(miscell->tl_out, "false");
        break;
    case TRUE:
        fprintf(miscell->tl_out, "true");
        break;
    case PREDICATE:
        fprintf(miscell->tl_out, "(%s)", n->sym->name);
        break;
    case -1:
        fprintf(miscell->tl_out, " D ");
        break;
    default:
        printf("Unknown token: ");
        tl_explain(n->ntyp);
        break;
    }
}

void tl_explain(int n)
{
    switch (n) {
    case ALWAYS:    printf("[]"); break;
    case EVENTUALLY: printf("<>"); break;
    case IMPLIES:   printf("->"); break;
    case EQUIV: printf("<->"); break;
    case PREDICATE: printf("predicate"); break;
    case OR:    printf("||"); break;
    case AND:   printf("&&"); break;
    case NOT:   printf("!"); break;
    case U_OPER:    printf("U"); break;
    case V_OPER:    printf("V"); break;
    case NEXT:  printf("X"); break;
    case TRUE:  printf("true"); break;
    case FALSE: printf("false"); break;
    case ';':   printf("end of formula"); break;
    default:    printf("%c", n); break;
    }
}

static void non_fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
    int i;

    printf("TaLiRo: ");
    if (s2)
        printf(s1, s2);
    else
        printf(s1);
    if ((*tl_yychar) != -1 && (*tl_yychar) != 0)
    {   printf(", saw '");
        tl_explain((*tl_yychar));
        printf("'");
    }
    printf("\nTaLiRo: %s\n---------", uform);
    for (i = 0; i < (*cnt); i++)
        printf("-");
    printf("^\n");
    fflush(stdout);
    (miscell->tl_errs)++;
}

void
tl_yyerror(char *s1, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
    Fatal(s1, (char *) 0, cnt, uform, tl_yychar, miscell);
}

void
Fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
  non_fatal(s1, s2, cnt, uform, tl_yychar, miscell);
  tl_exit(0);
}

void fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
        non_fatal(s1, s2, cnt, uform, tl_yychar, miscell);
        tl_exit(0);
}

void put_uform(char *uform, Miscellaneous *miscell)
{
    fprintf(miscell->tl_out, "%s", uform);
}

void tl_exit(int i)
{
    mexErrMsgTxt("mx_dp_taliro: unexpected error, tl_exit executed.");
}

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{   
    /* Variables needed to process the input */
    int status, pstatus;
    mwSize buflen, pbuflen;
    size_t NElems,NCells;
    mwSize ndimA, ndimb, ndimG, ndim, pdim,ndimP;
    const mwSize *dimsA, *dimsb, *dimsG, *dims, *pardims,*dimsP;
    mwIndex jstruct, iii, jjj, i1, j1, idx_j;
    mxArray *tmp,*tmp1,*tmp_cell;   
    /* Variables needed for monitor */
    Node *node;
    double *XTrace, *TStamps, *LTrace;
    DistCompData distData;
    PMap *predMap; 
    int ii,jj,kk,ll,objs,tempI;
    bool par_on;
    bool is_Multi_HA;
    bool initial_of_par;
    int npred, npar;

    static char uform[BUFF_LEN];
    static size_t hasuform=0;
    static int *cnt;
    int temp = 0;
    Miscellaneous *miscell = (Miscellaneous *) emalloc(sizeof(Miscellaneous));
    int *tl_yychar = (int *) emalloc(sizeof(int));
    miscell->dp_taliro_param.LTL = 1; 
    miscell->dp_taliro_param.ConOnSamples = 0; 
    miscell->dp_taliro_param.SysDim = 0; 
    miscell->dp_taliro_param.nSamp = 0; 
    miscell->dp_taliro_param.nPred = 0; 
    miscell->dp_taliro_param.true_nPred = 0; 
    miscell->dp_taliro_param.tnLoc = 0; 
    miscell->dp_taliro_param.nInp = 0; 
    miscell->dp_taliro_param.nCLG = 0;
    miscell->tl_errs = 0;
    miscell->type_temp = 0;

    /* Reset cnt to 0:
        cnt is the counter that points to the next symbol in the formula
        to be processed. This is a static variable and it retains its 
        value between Matlab calls to mx_dp_taliro. */
    cnt = &temp;

    /* Other initializations */
    miscell->dp_taliro_param.nInp = nrhs;
    par_on = false;
    initial_of_par = false;
    npred = 0;
    npar= 0;

    /* Make sure the I/O are in the right form */
    if(nrhs < 3)
        mexErrMsgTxt("mx_dp_taliro: At least 3 inputs are required.");
    else if(nlhs > 1)
      mexErrMsgTxt("mx_dp_taliro: Too many output arguments.");
    else if(nrhs > 8)
      mexErrMsgTxt("mx_dp_taliro: Too many input arguments.");
    else if(!mxIsChar(prhs[0]))
      mexErrMsgTxt("mx_dp_taliro: 1st input must be a string with TL formula.");
    else if(!mxIsStruct(prhs[1]))
      mexErrMsgTxt("mx_dp_taliro: 2nd input must be a structure (predicate map).");
    else if(!mxIsDouble(prhs[2]))
      mexErrMsgTxt("mx_dp_taliro: 3rd input must be a numerical array (State trace).");
    else if(nrhs>3 && !mxIsDouble(prhs[3]))
      mexErrMsgTxt("mx_dp_taliro: 4th input must be a numerical array (Time stamps).");
    else if(nrhs>5 && !mxIsDouble(prhs[4]))
      mexErrMsgTxt("mx_dp_taliro: 5th input must be a numerical array (Location trace).");
    else if(nrhs>5 && !(mxIsDouble(prhs[5])||mxIsCell(prhs[5])))
      mexErrMsgTxt("mx_dp_taliro: 6th input must be a numerical array \n (Minimum path distance to each control location for each predicate).");
    else if(nrhs>7 && !(mxIsCell(prhs[6])))
      mexErrMsgTxt("mx_dp_taliro: 7th input must be a cell array (Adjacency list).");
    else if(nrhs>7 && !(mxIsStruct(prhs[7])||mxIsCell(prhs[7])))
      mexErrMsgTxt("mx_dp_taliro: 8th input must be a structure (guard map).");

    if(nlhs > 1)
        mexErrMsgTxt("Too many output arguments.");
    plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);

    /* Process inputs */

    /* Get the formula */
    ndim = mxGetNumberOfDimensions(prhs[0]);
    dims = mxGetDimensions(prhs[0]);
    buflen = dims[1]*sizeof(mxChar)+1;
    if (buflen >= BUFF_LEN)
    {
      mexPrintf("%s%d%s\n", "The formula must be less than ", BUFF_LEN," characters.");
      mexErrMsgTxt("mx_dp_taliro: Formula too long.");
    }
    status = mxGetString(prhs[0], uform, buflen);   
    hasuform = strlen(uform);
    for (iii=0; iii<hasuform; iii++)
    {
        if (uform[iii] == '\t' || uform[iii] == '\"' || uform[iii] == '\n')                     
            uform[iii] = ' ';
    }

    /* Get state trace */       
    ndim = mxGetNumberOfDimensions(prhs[2]);
    if (ndim>2)
        mexErrMsgTxt("mx_dp_taliro: The state trace is not in proper form!"); 
    dims = mxGetDimensions(prhs[2]);
    miscell->dp_taliro_param.nSamp = dims[0];
    miscell->dp_taliro_param.SysDim = dims[1];
    XTrace = mxGetPr(prhs[2]);

    /* Get time stamps */      
    if (nrhs>3)
    {
        ndim = mxGetNumberOfDimensions(prhs[3]);
        if (ndim>2)
            mexErrMsgTxt("mx_dp_taliro: The time stamp sequence is not in proper form!"); 
        dims = mxGetDimensions(prhs[3]);
        if (miscell->dp_taliro_param.nSamp != dims[0])
            mexErrMsgTxt("mx_dp_taliro: The lengths of the time stamp sequence and the state trace do not match!"); 
        TStamps = mxGetPr(prhs[3]);
    }

    /* Get location trace and location graph */    
    if (nrhs>4)
    {
        ndim = mxGetNumberOfDimensions(prhs[4]);
        if (ndim>2)
            mexErrMsgTxt("mx_dp_taliro: The location trace is not in proper form!"); 
        dims = mxGetDimensions(prhs[4]);
        if (miscell->dp_taliro_param.nSamp != dims[0])
            mexErrMsgTxt("mx_dp_taliro: The lengths of the location trace and the state trace do not match!"); 
        LTrace = mxGetPr(prhs[4]);

        /* For Multiple H.A.s is added  */
        if(nrhs>5 && (mxIsCell(prhs[5]))){/*  For Multiple H.A.s */
            is_Multi_HA=1;
        miscell->dp_taliro_param.nCLG = dims[1];
            ndim = mxGetNumberOfDimensions(prhs[5]);
            if (ndim>2)
            {
                mexErrMsgTxt("mx_dp_taliro.c: !"); 
            }
            dims = mxGetDimensions(prhs[5]);
            if (dims[0]!=1)
            {
                mexErrMsgTxt("mx_dp_taliro: DMin is a cell, it must be a column vector cell!"); 
            }
            if (dims[1]!=miscell->dp_taliro_param.nCLG)
            {
                mexErrMsgTxt("mx_dp_taliro: DMin is a cell, it must be of the size of nCLG!"); 
            }
            distData.LDistNCLG = (double **)emalloc((miscell->dp_taliro_param.nCLG)*sizeof(double*));
            miscell->dp_taliro_param.tnLocNCLG = (mwSize*)emalloc((miscell->dp_taliro_param.nCLG)*sizeof(mwSize));
            for(kk=0; kk<miscell->dp_taliro_param.nCLG; kk++){
                tmp = mxGetCell(prhs[5],kk);
                dims = mxGetDimensions(tmp);
                miscell->dp_taliro_param.tnLocNCLG[kk] = dims[0];
                distData.LDistNCLG[kk]=mxGetPr(tmp);
            }
        }
        else if(nrhs>5) {/*  For Single H.A. */
            is_Multi_HA=0;
            ndim = mxGetNumberOfDimensions(prhs[5]);
            if (ndim>2)
                mexErrMsgTxt("mx_dp_taliro: The minimum distance array is not in proper form!"); 
            dims = mxGetDimensions(prhs[5]);
            miscell->dp_taliro_param.tnLoc = dims[0];
            distData.LDist = mxGetPr(prhs[5]);
        }

    }

}

1 Ответ

0 голосов
/ 18 февраля 2020

В вашем коде вы используете множество функций и типов данных, предоставляемых MEX API. Поэтому, если вы хотите создать «нормальный» C -код, вам придется полностью реорганизовать ваш код.

Но одним из возможных решений может быть компиляция исходного кода вне MATLAB IDE, с помощью g cc или любой другой компилятор. В этом случае вам нужно будет включить все необходимые файлы заголовков и ссылки на все библиотеки, которые вам нужны. Следуйте по ссылке, чтобы найти довольно хорошую документацию от Mathworks:

https://de.mathworks.com/matlabcentral/answers/377799-compiling-mex-files-without-the-mex-command

Другой способ создания C кода из Matlab Scipts / Functions - использовать MATLAB Кодер:

https://de.mathworks.com/products/matlab-coder.html

Надеюсь, что это полезно.

...