错误 LNK2019:无法解析的外部符号 (Matlab)

error LNK 2019: unresolved external symbol (Matlab)

我正在尝试在 Matlab 中构建一个 C mex 文件。 C 编译器是 Microsoft Visual C++ 2012,我使用的是 Matlab R2014a。这是我使用的确切命令:

mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c'

错误信息如下: 使用 'Microsoft Visual C++ 2012 (C)'.

构建
> Building with 'Microsoft Visual C++ 2012 (C)'. Error using mex   
> Creating library DynamicProgrammingQ2.lib and object
> DynamicProgrammingQ2.exp DynamicProgrammingQ2.obj : error LNK2019:
> unresolved external symbol dp_costs referenced in function mexFunction
> DynamicProgrammingQ2.obj : error LNK2019: unresolved external symbol
> dp_build_gamma referenced in function mexFunction
> DynamicProgrammingQ2.obj : error LNK2019: unresolved external symbol
> dp_all_indexes referenced in function mexFunction
> DynamicProgrammingQ2.mexw64 : fatal error LNK1120: 3 unresolved
> externals

这是 C 代码:

#include "mex.h"
#include <math.h>
#include "dp_grid.h"


/* Signature:
 * function [G T] = dp_mex( Q1, T1, Q2, T2, tv1, tv2 )
 * Arguments are checked in dp.m, not here.  */
void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]){
  double *Q1 = 0;
  double *T1 = 0;
  double *Q2 = 0;
  double *T2 = 0;
  double *lam1 = 0;
  double lam;
  int nsamps1;
  int nsamps2;
  double *tv1 = 0;
  double *tv2 = 0;
  int *idxv1 = 0;
  int *idxv2 = 0;
  int ntv1;
  int ntv2;
  double *G = 0;
  double *T = 0;
  int Gsize;
  int dim = 0;
  double *E = 0; /* E[ntv1*j+i] = cost of best path to (tv1[i],tv2[j]) */
  int *P = 0; /* P[ntv1*j+i] = predecessor of (tv1[i],tv2[j]) along best path */
  double m, rootm;
  int sr, sc; /* source row and column index */
  int tr, tc; /* target row and column index */
  int Galloc_size;
  double *pres;

  /* [G T dist] = dp_mex( Q1, T1, Q2, T2, tv1, tv2 ); */
  Q1 = mxGetPr( prhs[0] );
  T1 = mxGetPr( prhs[1] );
  Q2 = mxGetPr( prhs[2] );
  T2 = mxGetPr( prhs[3] );
  tv1 = mxGetPr( prhs[4] );
  tv2 = mxGetPr( prhs[5] );
  lam1 = mxGetPr( prhs[6] );
  lam = *lam1;

  dim = mxGetM( prhs[0] );
  nsamps1 = mxGetN( prhs[1] ); /* = columns(T1) = columns(Q1)+1 */
  nsamps2 = mxGetN( prhs[3] ); /* = columns(T2) = columns(Q2)+1 */
  ntv1 = mxGetN( prhs[4] );
  ntv2 = mxGetN( prhs[5] );
  Galloc_size = ntv1>ntv2 ? ntv1 : ntv2;


  if ( !(idxv1=(int*)mxMalloc(ntv1*sizeof(int))) )
  {
    mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate idxv1" );
    goto cleanup;
  }
  if ( !(idxv2=(int*)mxMalloc(ntv2*sizeof(int))) )
  {
    mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate idxv2" );
    goto cleanup;
  }
  if ( !(E=(double*)mxMalloc(ntv1*ntv2*sizeof(double))) )
  { 
    mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate E" );
    goto cleanup;
  }
  if ( !(P=(int*)mxCalloc(ntv1*ntv2,sizeof(int))) )
  { 
    mexErrMsgIdAndTxt( "dp:AllocFailed", "failed to allocate P" );
    goto cleanup;
  }
  if ( !(plhs[0]=mxCreateDoubleMatrix(1,Galloc_size,mxREAL)) )
  { 
    mexErrMsgIdAndTxt( "dp:AllocFailed", "mxCreateDoubleMatrix failed" );
    goto cleanup;
  }
  if ( !(plhs[1]=mxCreateDoubleMatrix(1,Galloc_size,mxREAL)) )
  { 
    mexErrMsgIdAndTxt( "dp:AllocFailed", "mxCreateDoubleMatrix failed" );
    goto cleanup;
  }
  if ( !(plhs[2]=mxCreateDoubleScalar(0.0)) )
  { 
    mexErrMsgIdAndTxt( "dp:AllocFailed", "mxCreateDoubleScalar failed" );
    goto cleanup;
  }

  G = mxGetPr( plhs[0] );
  T = mxGetPr( plhs[1] );
  pres = mxGetPr( plhs[2] );

  /* dp_costs() needs indexes for gridpoints precomputed */
  dp_all_indexes( T1, nsamps1, tv1, ntv1, idxv1 );
  dp_all_indexes( T2, nsamps2, tv2, ntv2, idxv2 );

  /* Compute cost of best path from (0,0) to every other grid point */
  *pres = dp_costs( Q1, T1, nsamps1, Q2, T2, nsamps2, 
    dim, tv1, idxv1, ntv1, tv2, idxv2, ntv2, E, P, lam );

  /* Reconstruct best path from (0,0) to (1,1) */
  Gsize = dp_build_gamma( P, tv1, ntv1, tv2, ntv2, G, T );
  mxSetN( plhs[0], Gsize );
  mxSetN( plhs[1], Gsize );

cleanup:
  if ( idxv1 ) mxFree( idxv1 );
  if ( idxv2 ) mxFree( idxv2 );
  if ( E ) mxFree( E );
  if ( P ) mxFree( P );
}

这是头文件:

#ifndef DP_GRID_H
#define DP_GRID_H 1

/**
 * Computes weights of all edges in the DP matching graph, 
 * which is needed for the Floyd-Warshall all-pairs shortest-path 
 * algorithm.
 *
 * The matrix of edge weights E must be allocated ahead of time by 
 * the caller.  E is an ntv1 x ntv2 x ntv1 x ntv2 matrix.  If i and k 
 * are column indices and j and l are row indices, then the weight of the 
 * edge from gridpoint (tv1[i],tv2[j]) to gridpoint (tv1[k],tv2[l]) is 
 * stored in E(j,i,l,k) when this function returns.
 * Mapping: 
 *  (j,i,l,k) :--> j*ntv1*ntv2*ntv1 + 
 *                 i*ntv2*ntv1 +
 *                 l*ntv1 + 
 *                 k
 *
 * \param Q1 values of the first SRVF
 * \param T1 changepoint parameters of the first SRVF
 * \param nsamps1 the length of T1
 * \param Q2 values of the second SRVF
 * \param T2 changepoint parameters of the second SRVF
 * \param nsamps2 the length of T2
 * \param dim dimension of the ambient space
 * \param tv1 the Q1 (column) parameter values for the DP grid
 * \param idxv1 Q1 indexes for tv1, as computed by \c dp_all_indexes()
 * \param ntv1 the length of tv1
 * \param tv2 the Q2 (row) parameter values for the DP grid
 * \param idxv2 Q2 indexes for tv2, as computed by \c dp_all_indexes()
 * \param ntv2 the length of tv2
 * \param E [output] pointer to the edge weight matrix.  Must already be 
 *          allocated, with size (ntv1*ntv2)^2.
 */
void dp_all_edge_weights( 
  double *Q1, double *T1, int nsamps1,
  double *Q2, double *T2, int nsamps2,
  int dim, 
  double *tv1, int *idxv1, int ntv1, 
  double *tv2, int *idxv2, int ntv2, 
  double *W, double lam );

/**
 * Computes cost of best path from (0,0) to all other gridpoints.
 *
 * \param Q1 values of the first SRVF
 * \param T1 changepoint parameters of the first SRVF
 * \param nsamps1 the length of T1
 * \param Q2 values of the second SRVF
 * \param T2 changepoint parameters of the second SRVF
 * \param nsamps2 the length of T2
 * \param dim dimension of the ambient space
 * \param tv1 the Q1 (column) parameter values for the DP grid
 * \param idxv1 Q1 indexes for tv1, as computed by \c dp_all_indexes()
 * \param ntv1 the length of tv1
 * \param tv2 the Q2 (row) parameter values for the DP grid
 * \param idxv2 Q2 indexes for tv2, as computed by \c dp_all_indexes()
 * \param ntv2 the length of tv2
 * \param E [output] on return, E[ntv2*i+j] holds the cost of the best 
 *        path from (0,0) to (tv1[i],tv2[j]) in the grid.
 * \param P [output] on return, P[ntv2*i+j] holds the predecessor of 
 *        (tv1[i],tv2[j]).  If predecessor is (tv1[k],tv2[l]), then 
 *        P[ntv2*i+j] = k*ntv2+l.
 * \return E[ntv1*ntv2-1], the cost of the best path from (tv1[0],tv2[0]) 
 *         to (tv1[ntv1-1],tv2[ntv2-1]).
 */
double dp_costs(
  double *Q1, double *T1, int nsamps1, 
  double *Q2, double *T2, int nsamps2,
  int dim, 
  double *tv1, int *idxv1, int ntv1, 
  double *tv2, int *idxv2, int ntv2, 
  double *E, int *P, double lam );

/**
 * Computes the weight of the edge from (a,c) to (b,d) in the DP grid.
 *
 * \param Q1 values of the first SRVF
 * \param T1 changepoint parameters of the first SRVF
 * \param nsamps1 the length of T1
 * \param Q2 values of the second SRVF
 * \param T2 changepoint parameters of the second SRVF
 * \param nsamps2 the length of T2
 * \param dim dimension of the ambient space
 * \param a source Q1 parameter
 * \param b target Q1 parameter
 * \param c source Q2 parameter
 * \param d target Q2 parameter
 * \param aidx index such that Q1[aidx] <= a < Q1[aidx+1]
 * \param cidx index such that Q2[cidx] <= c < Q2[cidx+1]
 */
  double dp_edge_weight(
  double *Q1, double *T1, int nsamps1, 
  double *Q2, double *T2, int nsamps2,
  int dim,
  double a, double b, 
  double c, double d, 
  int aidx, int cidx, double lam );


/**
 * Given predecessor table P, builds the piecewise-linear reparametrization 
 * function gamma.
 *
 * G and T must already be allocated with size max(ntv1,ntv2).  The actual 
 * number of points on gamma will be the return value.
 *
 * \param P P[ntv2*i+j] holds the predecessor of (tv1[i],tv2[j]).  If 
 *        predecessor is (tv1[k],tv2[l]), then P[ntv2*i+j] = k*ntv2+l.
 * \param tv1 the Q1 (column) parameter values for the DP grid
 * \param ntv1 the length of tv1
 * \param tv2 the Q2 (row) parameter values for the DP grid
 * \param ntv2 the length of tv2
 * \param G [output] reparametrization function values
 * \param T [output] reparametrization changepoint parameters
 * \return the length of G (same as length of T).
 */
int dp_build_gamma( 
  int *P, 
  double *tv1, int ntv1, 
  double *tv2, int ntv2,
  double *G, double *T );

/**
 * Given t in [0,1], return the integer i such that t lies in the interval 
 * [T[i],T[i+1]) (or returns n-2 if t==T[n-1]).
 *
 * \param T an increasing sequence
 * \param n the length of T
 * \param t the parameter value to lookup ( T[0] <= t <= T[n-1] ).
 * \return the integer i such that t lies in the interval [T[i],T[i+1]) 
 *         (or n-2 if t==T[n-1]).
 */
int dp_lookup( double *T, int n, double t );

/**
 * 1-D table lookup for a sorted array of query points.
 *
 * Given a partition p and an increasing sequence of numbers tv between 
 * p[0] and p[np-1], computes the sequence of indexes idxv such that for 
 * i=0,...,ntv-1, p[idxv[i]] <= tv[i] < p[idxv[i]+1].  If tv[i]==p[np-1], 
 * then idxv[i] will be set to np-2.
 *
 * \param p an increasing sequence (the table)
 * \param np the length of \a p
 * \param tv an increasing sequence (the query points)
 * \param ntv the length of \a tv
 * \param idxv [output] pre-allocated array of \a ntv ints to hold result
 */
void dp_all_indexes( double *p, int np, double *tv, int ntv, int *idxv );

#endif /* DP_GRID_H */

#ifndef DP_NBHD_H
#define DP_NBHD_H 1

#ifndef DP_NBHD_DIM
#define DP_NBHD_DIM 7 
#endif

#if DP_NBHD_DIM == 17
int dp_nbhd[][2] = {
{  1,  1 }, {  1,  2 }, {  1,  3 }, {  1,  4 }, {  1,  5 }, {  1,  6 }, {  1,  7 }, {  1,  8 }, {  1,  9 }, {  1, 10 }, 
{  1, 11 }, {  1, 12 }, {  1, 13 }, {  1, 14 }, {  1, 15 }, {  1, 16 }, {  1, 17 }, {  2,  1 }, {  2,  3 }, {  2,  5 }, 
{  2,  7 }, {  2,  9 }, {  2, 11 }, {  2, 13 }, {  2, 15 }, {  2, 17 }, {  3,  1 }, {  3,  2 }, {  3,  4 }, {  3,  5 }, 
{  3,  7 }, {  3,  8 }, {  3, 10 }, {  3, 11 }, {  3, 13 }, {  3, 14 }, {  3, 16 }, {  3, 17 }, {  4,  1 }, {  4,  3 }, 
{  4,  5 }, {  4,  7 }, {  4,  9 }, {  4, 11 }, {  4, 13 }, {  4, 15 }, {  4, 17 }, {  5,  1 }, {  5,  2 }, {  5,  3 }, 
{  5,  4 }, {  5,  6 }, {  5,  7 }, {  5,  8 }, {  5,  9 }, {  5, 11 }, {  5, 12 }, {  5, 13 }, {  5, 14 }, {  5, 16 }, 
{  5, 17 }, {  6,  1 }, {  6,  5 }, {  6,  7 }, {  6, 11 }, {  6, 13 }, {  6, 17 }, {  7,  1 }, {  7,  2 }, {  7,  3 }, 
{  7,  4 }, {  7,  5 }, {  7,  6 }, {  7,  8 }, {  7,  9 }, {  7, 10 }, {  7, 11 }, {  7, 12 }, {  7, 13 }, {  7, 15 }, 
{  7, 16 }, {  7, 17 }, {  8,  1 }, {  8,  3 }, {  8,  5 }, {  8,  7 }, {  8,  9 }, {  8, 11 }, {  8, 13 }, {  8, 15 }, 
{  8, 17 }, {  9,  1 }, {  9,  2 }, {  9,  4 }, {  9,  5 }, {  9,  7 }, {  9,  8 }, {  9, 10 }, {  9, 11 }, {  9, 13 }, 
{  9, 14 }, {  9, 16 }, {  9, 17 }, { 10,  1 }, { 10,  3 }, { 10,  7 }, { 10,  9 }, { 10, 11 }, { 10, 13 }, { 10, 17 }, 
{ 11,  1 }, { 11,  2 }, { 11,  3 }, { 11,  4 }, { 11,  5 }, { 11,  6 }, { 11,  7 }, { 11,  8 }, { 11,  9 }, { 11, 10 }, 
{ 11, 12 }, { 11, 13 }, { 11, 14 }, { 11, 15 }, { 11, 16 }, { 11, 17 }, { 12,  1 }, { 12,  5 }, { 12,  7 }, { 12, 11 }, 
{ 12, 13 }, { 12, 17 }, { 13,  1 }, { 13,  2 }, { 13,  3 }, { 13,  4 }, { 13,  5 }, { 13,  6 }, { 13,  7 }, { 13,  8 }, 
{ 13,  9 }, { 13, 10 }, { 13, 11 }, { 13, 12 }, { 13, 14 }, { 13, 15 }, { 13, 16 }, { 13, 17 }, { 14,  1 }, { 14,  3 }, 
{ 14,  5 }, { 14,  9 }, { 14, 11 }, { 14, 13 }, { 14, 15 }, { 14, 17 }, { 15,  1 }, { 15,  2 }, { 15,  4 }, { 15,  7 }, 
{ 15,  8 }, { 15, 11 }, { 15, 13 }, { 15, 14 }, { 15, 16 }, { 15, 17 }, { 16,  1 }, { 16,  3 }, { 16,  5 }, { 16,  7 }, 
{ 16,  9 }, { 16, 11 }, { 16, 13 }, { 16, 15 }, { 16, 17 }, { 17,  1 }, { 17,  2 }, { 17,  3 }, { 17,  4 }, { 17,  5 }, 
{ 17,  6 }, { 17,  7 }, { 17,  8 }, { 17,  9 }, { 17, 10 }, { 17, 11 }, { 17, 12 }, { 17, 13 }, { 17, 14 }, { 17, 15 }, 
{ 17, 16 }, };
#define DP_NBHD_COUNT 191

#elif DP_NBHD_DIM == 12
int dp_nbhd[][2] = {
{  1,  1 }, {  1,  2 }, {  1,  3 }, {  1,  4 }, {  1,  5 }, {  1,  6 }, {  1,  7 }, {  1,  8 }, {  1,  9 }, {  1, 10 }, 
{  1, 11 }, {  1, 12 }, {  2,  1 }, {  2,  3 }, {  2,  5 }, {  2,  7 }, {  2,  9 }, {  2, 11 }, {  3,  1 }, {  3,  2 }, 
{  3,  4 }, {  3,  5 }, {  3,  7 }, {  3,  8 }, {  3, 10 }, {  3, 11 }, {  4,  1 }, {  4,  3 }, {  4,  5 }, {  4,  7 }, 
{  4,  9 }, {  4, 11 }, {  5,  1 }, {  5,  2 }, {  5,  3 }, {  5,  4 }, {  5,  6 }, {  5,  7 }, {  5,  8 }, {  5,  9 }, 
{  5, 11 }, {  5, 12 }, {  6,  1 }, {  6,  5 }, {  6,  7 }, {  6, 11 }, {  7,  1 }, {  7,  2 }, {  7,  3 }, {  7,  4 }, 
{  7,  5 }, {  7,  6 }, {  7,  8 }, {  7,  9 }, {  7, 10 }, {  7, 11 }, {  7, 12 }, {  8,  1 }, {  8,  3 }, {  8,  5 }, 
{  8,  7 }, {  8,  9 }, {  8, 11 }, {  9,  1 }, {  9,  2 }, {  9,  4 }, {  9,  5 }, {  9,  7 }, {  9,  8 }, {  9, 10 }, 
{  9, 11 }, { 10,  1 }, { 10,  3 }, { 10,  7 }, { 10,  9 }, { 10, 11 }, { 11,  1 }, { 11,  2 }, { 11,  3 }, { 11,  4 }, 
{ 11,  5 }, { 11,  6 }, { 11,  7 }, { 11,  8 }, { 11,  9 }, { 11, 10 }, { 11, 12 }, { 12,  1 }, { 12,  5 }, { 12,  7 }, 
{ 12, 11 } };
#define DP_NBHD_COUNT 91

#elif DP_NBHD_DIM == 10

int dp_nbhd[][2] = {
{  1,  1 }, {  1,  2 }, {  1,  3 }, {  1,  4 }, {  1,  5 }, {  1,  6 }, {  1,  7 }, {  1,  8 }, {  1,  9 }, {  1, 10 }, 
{  2,  1 }, {  2,  3 }, {  2,  5 }, {  2,  7 }, {  2,  9 }, {  3,  1 }, {  3,  2 }, {  3,  4 }, {  3,  5 }, {  3,  7 }, 
{  3,  8 }, {  3, 10 }, {  4,  1 }, {  4,  3 }, {  4,  5 }, {  4,  7 }, {  4,  9 }, {  5,  1 }, {  5,  2 }, {  5,  3 }, 
{  5,  4 }, {  5,  6 }, {  5,  7 }, {  5,  8 }, {  5,  9 }, {  6,  1 }, {  6,  5 }, {  6,  7 }, {  7,  1 }, {  7,  2 }, 
{  7,  3 }, {  7,  4 }, {  7,  5 }, {  7,  6 }, {  7,  8 }, {  7,  9 }, {  7, 10 }, {  8,  1 }, {  8,  3 }, {  8,  5 }, 
{  8,  7 }, {  8,  9 }, {  9,  1 }, {  9,  2 }, {  9,  4 }, {  9,  5 }, {  9,  7 }, {  9,  8 }, {  9, 10 }, { 10,  1 }, 
{ 10,  3 }, { 10,  7 }, { 10,  9 } };
#define DP_NBHD_COUNT 63

#elif DP_NBHD_DIM == 7

int dp_nbhd[][2] = {
{  1,  1 }, {  1,  2 }, {  1,  3 }, {  1,  4 }, {  1,  5 }, {  1,  6 }, {  1,  7 }, {  2,  1 }, {  2,  3 }, {  2,  5 }, 
{  2,  7 }, {  3,  1 }, {  3,  2 }, {  3,  4 }, {  3,  5 }, {  3,  7 }, {  4,  1 }, {  4,  3 }, {  4,  5 }, {  4,  7 }, 
{  5,  1 }, {  5,  2 }, {  5,  3 }, {  5,  4 }, {  5,  6 }, {  5,  7 }, {  6,  1 }, {  6,  5 }, {  6,  7 }, {  7,  1 }, 
{  7,  2 }, {  7,  3 }, {  7,  4 }, {  7,  5 }, {  7,  6 }, };
#define DP_NBHD_COUNT 35

#else
int dp_nbhd[][2] = {
{  1,  1 }, {  1,  2 }, {  1,  3 }, {  1,  4 }, {  1,  5 }, {  1,  6 }, {  2,  1 }, {  2,  3 }, {  2,  5 }, {  3,  1 }, 
{  3,  2 }, {  3,  4 }, {  3,  5 }, {  4,  1 }, {  4,  3 }, {  4,  5 }, {  5,  1 }, {  5,  2 }, {  5,  3 }, {  5,  4 }, 
{  5,  6 }, {  6,  1 }, {  6,  5 }, };
#define DP_NBHD_COUNT 23

#endif  /* DP_NBHD_DIM */

#endif  /* DP_NBHD_H */

另外还有一个C文件:

#include <stdio.h>
#include <math.h>
#include "dp_nbhd.h"
#include "dp_grid.h"


void dp_all_edge_weights( 
  double *Q1, double *T1, int nsamps1,
  double *Q2, double *T2, int nsamps2,
  int dim, 
  double *tv1, int *idxv1, int ntv1, 
  double *tv2, int *idxv2, int ntv2, 
  double *W, double lam )
{
  int sr, sc;  /* source row and column */
  int tr, tc;  /* target row and column */
  int l1, l2, l3;  /* for multidimensional array mapping */
  int i;

  for ( i=0; i<ntv1*ntv2*ntv1*ntv2; W[i++]=1e6 );

  /* W is a ntv2 x ntv1 x ntv2 x ntv1 array.  
   * Weight of edge from (tv1[i],tv2[j]) to (tv1[k],tv2[l]) 
   * (Cartesian coordinates) is in grid(j,i,l,k).
   * Mapping: 
   *  (j,i,l,k) :--> j*ntv1*ntv2*ntv1 + 
   *                 i*ntv2*ntv1 +
   *                 l*ntv1 + 
   *                 k
   */
  l1 = ntv1 * ntv2 * ntv1;
  l2 = ntv2 * ntv1;
  l3 = ntv1;

  for ( tr=1; tr<ntv2; ++tr )
  {
    for ( tc=1; tc<ntv1; ++tc )
    {
      for ( i=0; i<DP_NBHD_COUNT; ++i )
      {
        sr = tr - dp_nbhd[i][0];
        sc = tc - dp_nbhd[i][1];

        if ( sr < 0 || sc < 0 ) continue;

        /* grid(sr,sc,tr,tc) */
        W[sr*l1+sc*l2+tr*l3+tc] = 
         dp_edge_weight( Q1, T1, nsamps1, Q2, T2, nsamps2, dim, 
           tv1[sc], tv1[tc], tv2[sr], tv2[tr], idxv1[sc], idxv2[sr], lam );

        /*
        printf( "(%0.2f,%0.2f) --> (%0.2f,%0.2f) = %0.2f\n", 
          a, c, b, d, grid[sr*l1+sc*l2+tr*l3+tc] );
        */
      }
    }
  }
}


double dp_costs(
  double *Q1, double *T1, int nsamps1, 
  double *Q2, double *T2, int nsamps2,
  int dim, 
  double *tv1, int *idxv1, int ntv1, 
  double *tv2, int *idxv2, int ntv2, 
  double *E, int *P, double lam )
{
  int sr, sc;  /* source row and column */
  int tr, tc;  /* target row and column */
  double w, cand_cost;
  int i;

  E[0] = 0.0;
  for ( i=1; i<ntv1; E[i++]=1e9 );
  for ( i=1; i<ntv2; E[ntv1*i++]=1e9 );

  for ( tr=1; tr<ntv2; ++tr )
  {
    for ( tc=1; tc<ntv1; ++tc )
    {
      E[ntv1*tr + tc] = 1e9;

      for ( i=0; i<DP_NBHD_COUNT; ++i )
      {
        sr = tr - dp_nbhd[i][0];
        sc = tc - dp_nbhd[i][1];

        if ( sr < 0 || sc < 0 ) continue;

        w = dp_edge_weight( Q1, T1, nsamps1, Q2, T2, nsamps2, dim, 
          tv1[sc], tv1[tc], tv2[sr], tv2[tr], idxv1[sc], idxv2[sr], lam );

        cand_cost = E[ntv1*sr+sc] + w;
        if ( cand_cost < E[ntv1*tr+tc] )
        {
          E[ntv1*tr+tc] = cand_cost;
          P[ntv1*tr+tc] = ntv1*sr + sc;
        }
      }
    }
  }

  /*
  for ( tr=1; tr<ntv2; ++tr )
  {
    for ( tc=1; tc<ntv1; ++tc )
    {
      printf( "E[%d,%d]=%0.3f, ", tr, tc, E[ntv1*tr+tc] );
      printf( "P[%d,%d]=(%d,%d)\n", tr, tc, P[ntv1*tr+tc]/ntv1,
                                            P[ntv1*tr+tc]%ntv1 );
    }
  }
  */

  return E[ntv1*ntv2-1];
}


double dp_edge_weight(
  double *Q1, double *T1, int nsamps1, 
  double *Q2, double *T2, int nsamps2,
  int dim, 
  double a, double b, 
  double c, double d,
  int aidx, int cidx, double lam )
{
  double res = 0.0;
  int Q1idx, Q2idx;
  int Q1idxnext, Q2idxnext;
  double t1, t2;
  double t1next, t2next;
  double t1nextcand1, t1nextcand2;
  double slope, rslope;
  double dq, dqi;
  int i;

  Q1idx = aidx; /*dp_lookup( T1, nsamps1, a );*/
  Q2idx = cidx; /*dp_lookup( T2, nsamps2, c );*/

  t1 = a;
  t2 = c;

  slope = (d-c)/(b-a);
  rslope = sqrt( slope );

  while( t1 < b && t2 < d )
  {
    if ( Q1idx > nsamps1-2 || Q2idx > nsamps2-2 ) break;

    /* Find endpoint of current interval */
    t1nextcand1 = T1[Q1idx+1];
    t1nextcand2 = a + (T2[Q2idx+1]-c) / slope;

    if ( fabs(t1nextcand1-t1nextcand2) < 1e-6 )
    {
      t1next = T1[Q1idx+1];
      t2next = T2[Q2idx+1];
      Q1idxnext = Q1idx+1;
      Q2idxnext = Q2idx+1;
    } else if ( t1nextcand1 < t1nextcand2 ) {
      t1next = t1nextcand1;
      t2next = c + slope * (t1next - a);
      Q1idxnext = Q1idx+1;
      Q2idxnext = Q2idx;
    } else {
      t1next = t1nextcand2;
      t2next = T2[Q2idx+1];
      Q1idxnext = Q1idx;
      Q2idxnext = Q2idx+1;
    }

    if ( t1next > b ) t1next = b;
    if ( t2next > d ) t2next = d;

    /* Get contribution for current interval */
    dq = 0.0;
    for ( i=0; i<dim; ++i )
    {
      /* Q1 and Q2 are column-major arrays! */
      dqi = Q1[Q1idx*dim+i] - rslope * Q2[Q2idx*dim+i];
      dq += dqi*dqi + lam*(1-rslope)*(1-rslope);
    }
    res += (t1next - t1) * dq;

    t1 = t1next;
    t2 = t2next;
    Q1idx = Q1idxnext;
    Q2idx = Q2idxnext;
  }

  return res;
}


int dp_build_gamma( 
  int *P, 
  double *tv1, int ntv1, 
  double *tv2, int ntv2,
  double *G, double *T )
{
  int sr, sc;
  int tr, tc;
  int p, i;
  int npts;  /* result = length of Tg */

  /* Dry run first, to determine length of Tg */
  npts = 1;
  tr = ntv2-1;
  tc = ntv1-1;
  while( tr > 0 && tc > 0 )
  {
    p = P[tr*ntv1+tc];
    tr = p / ntv1;
    tc = p % ntv1;
    ++npts;
  }

  G[npts-1] = tv2[ntv2-1];
  T[npts-1] = tv1[ntv1-1];

  tr = ntv2-1;
  tc = ntv1-1;
  i = npts-2;
  while( tr > 0 && tc > 0 )
  {
    p = P[tr*ntv1+tc];
    sr = p / ntv1;
    sc = p % ntv1;

    G[i] = tv2[sr];
    T[i] = tv1[sc];

    tr = sr;
    tc = sc;
    --i;
  }

  return npts;
}


int dp_lookup( double *T, int n, double t )
{
  int l, m, r;

  if ( t < T[n-1] )
  {
    l=0;
    r=n;
    m=(l+r)/2;

    /* TODO: are these comparisons OK??? */
    while( 1 )
    {
      if ( t >= T[m+1] )
        l = m;
      else if ( t < T[m] )
        r = m;
      else
        break;

      m = (r+l)/2;
    }

    return m;
  } else {
    return n-2;
  }
}

void dp_all_indexes( double *p, int np, double *tv, int ntv, int *idxv )
{
  int pi;
  int i;

  pi=0;
  for ( i=0; i<ntv; ++i )
  {
    while ( pi < np-2 && tv[i] >= p[pi+1] ) ++pi;
    idxv[i] = pi;
  }
}

包含文件的目录在搜索路径上。我怎样才能克服这个错误并构建 C mex 文件?

看起来问题在于您只编译了 file1,它调用了 file2 的函数。因此,您在编译顺序中都需要它们。

怎么样

mex 'T:\Matlab\SRVF_FDA\DynamicProgrammingQ2.c' **SECOND FILE**?