2014-01-07 43 views
2

隐声明我用Matlab R2013b和Xcode的5.0.2我的MacBook到MEX文件使用Matlab的命令调用sfun_rttime.cmex sfun_rrtime.c的功能“分钟”

这将导致以下错误消息:

sfun_rttime.c:108:26: warning: implicit declaration of function 'min' is invalid in 
     C99 [-Wimplicit-function-declaration] 
    while (t_diff < (dt - min(dt,t_execution))) { 
         ^
1 warning generated. 
Undefined symbols for architecture x86_64: 
    "_min", referenced from: 
     _mdlOutputs in sfun_rttime.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

    mex: link of ' "sfun_rttime.mexmaci64"' failed. 

Unable to complete successfully. 

.c文件如下所示:

#define S_FUNCTION_LEVEL 2 
#define S_FUNCTION_NAME sfun_rttime 

#define TIME_SCALE_FACTOR(S) ssGetSFcnParam(S,0) 

/* Need to include simstruc.h for the definition of the SimStruct and 
* its associated macro definitions. */ 
#include <simstruc.h> 

#if defined(_WIN32) 
/* Include the windows SDK header for handling time functions. */ 
#include <windows.h> 
#include <math.h> 

/* Function of the high performance counter (in seconds). */ 
__inline double hightimer() 
{ 
    HANDLE hCurrentProcess = GetCurrentProcess(); 
    DWORD dwProcessAffinity; 
    DWORD dwSystemAffinity;  
    LARGE_INTEGER frequency, counter; 
    double sec_per_tick, total_ticks; 

    /* force thread on first cpu */ 
    GetProcessAffinityMask(hCurrentProcess,&dwProcessAffinity,&dwSystemAffinity); 
    SetProcessAffinityMask(hCurrentProcess, 1); 

    /* retrieves the frequency of the high-resolution performance counter */ 
    QueryPerformanceFrequency(&frequency); 

    /* retrieves the current value of the high-resolution performance counter */ 
    QueryPerformanceCounter(&counter); 

    /* reset thread */ 
    SetProcessAffinityMask(hCurrentProcess,dwProcessAffinity); 

    /* time in seconds */ 
    sec_per_tick = (double)1/(double)frequency.QuadPart; 
    total_ticks = (double)counter.QuadPart;  
    return sec_per_tick*total_ticks; 
} /* end hightimer */ 
#else 
/* Include the standard ANSI C header for handling time functions. */ 
#include <time.h> 

/* Function of the high performance counter (in seconds). */ 
__inline double hightimer() 
{  
    return (double)clock()/CLOCKS_PER_SEC; 
} /* end hightimer */ 
#endif 

static void mdlInitializeSizes(SimStruct *S) 
{ 
    ssSetNumSFcnParams(S, 1); /* Number of expected parameters */ 
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; 
    ssSetNumContStates(S, 0); 
    ssSetNumDiscStates(S, 1); 
    if (!ssSetNumInputPorts(S, 0)) return; 
    if (!ssSetNumOutputPorts(S, 1)) return; 
    ssSetOutputPortWidth(S, 0, 1); 
    ssSetNumSampleTimes(S, 1); 
    ssSetNumRWork(S, 1); 
    ssSetNumIWork(S, 0); 
    ssSetNumPWork(S, 0); 
    ssSetNumModes(S, 0); 
    ssSetNumNonsampledZCs(S, 0); 
    ssSetOptions(S, 0); 
} 

#define MDL_INITIALIZE_SAMPLE_TIMES 
static void mdlInitializeSampleTimes(SimStruct *S) 
{ 
    ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); 
    ssSetOffsetTime(S, 0, 0.0); 
} 

#define MDL_START 
static void mdlStart(SimStruct *S) 
{ 
    ssSetRWorkValue(S,0,ssGetTStart(S)); 
} 

static void mdlOutputs(SimStruct *S, int_T tid) 
{ 
    double   *t_x = ssGetDiscStates(S); 
    double   *t_y = ssGetOutputPortRealSignal(S,0); 
    double    t_previousSimTime = ssGetRWorkValue(S,0); 
    const double  *scaleFactor = mxGetPr(TIME_SCALE_FACTOR(S)); 
    time_T    t_SimTime = ssGetT(S); 
    double    t_diff = 0.0; 
    double    dt; 
    double    t_current; 
    double    t_0; 
    double    t_previous; 
    double    t_elapsed; 
    double    t_execution; 

    /* Desired Delta time */ 
    dt = (t_SimTime - t_previousSimTime)*(scaleFactor[0]); 

    /* Get clock time at the beginning of this step*/ 
    t_previous = hightimer(); 
    t_0 = t_previous; 

    /* Wait to reach the desired time */ 
    t_execution = t_0-t_x[0]; 
    while (t_diff < (dt - min(dt,t_execution))) { 
     t_current = hightimer(); 
     /* Look for wrapup */ 
     if (t_current<t_previous){ 
      t_elapsed = t_previous - t_0; 
      t_0 = hightimer() - t_elapsed; 
     } 
     t_diff = t_current - t_0; 
     t_previous = t_current; 
    } 

    /* Store current time to be used in next time step*/ 
    t_y[0] = dt - t_execution; 
    t_x[0] = t_previous; 
    ssSetRWorkValue(S,0,t_SimTime); 
} 

static void mdlTerminate(SimStruct *S) 
{ 
    UNUSED_ARG(S); /* unused input argument */ 
} 

/* Required S-function trailer */ 
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ 
#include "simulink.c"  /* MEX-file interface mechanism */ 
#else 
#include "cg_sfun.h"  /* Code generation registration function */ 
#endif 

我没有写这个文件我自己,也不我有一个线索,这有什么错吧。

+0

缺少头文件? –

+0

@Sourav Ghosh,没有线索,mexing这个文件是没有问题的另一台电脑上运行Windows。 – Pietair

+1

在C99中没有'min'函数或宏,'fmin'确实存在(加上它正确地处理NaN值,如果它们发生的话)。请注意,'windows.h'定义了它自己的最小/最大宏 – Amro

回答

6

在非Windows机器,你不#include <windows.h>(由于#ifdef和明显的其它原因)。 Windows.h拉在WinDef.hWinDef.h包含:

#ifndef min 
#define min(a,b)   (((a) < (b)) ? (a) : (b)) 
#endif 

这就是他去!

您可以实现宏,使用fmin()如前所述(注意当前math.h包括为#ifdef'd出过),或者如果你感觉真的并希望给连接正是什么正在查找:

double min(double a, double b) { 
    return a<b ? a : b; 
} 
3

如何使用“double fmin(double x,double y)”代替min如下?

... 
/* Include the standard ANSI C header for handling time functions. */ 
#include <time.h> 

#include <math.h> 
#define min(a,b) fmin(a,b) 
... 
+0

Integer没有一个方法'min',如果使用min(a,b),我会得到相同的错误' – Bionix1441