我在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
我自己没有写这个文件,也不知道它有什么问题。
答案 0 :(得分:7)
在非Windows计算机上,您没有#include <windows.h>
(由于#ifdef
以及明显的其他原因)。 Windows.h
引入WinDef.h
,WinDef.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)
...