函数'min'的隐式声明

时间:2014-01-07 20:06:43

标签: c matlab mex

我在MacBook上使用Matlab R2013b和Xcode 5.0.2使用Matlab的命令来调用名为sfun_rttime.c的文件:mex 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

我自己没有写这个文件,也不知道它有什么问题。

2 个答案:

答案 0 :(得分:7)

在非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也是如此),或者如果你感觉真的 kind,并希望链接器完全它正在寻找的东西:

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

答案 1 :(得分: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)
...