Invalid Mex file: Undefined symbol: mxrErrMsgTxt

20 visualizaciones (últimos 30 días)
Michael Hadler
Michael Hadler el 20 de Mayo de 2020
Comentada: James Tursa el 28 de Mayo de 2020
Hi everyone,
I've been trying to run a piece of code I downloaded from here (code below): CCG_mine
It's supposed to call a C code designed to quickly compute multiple cross-correlograms. In git, you will also find the corresponding mex-files.
I use Matlab 2020a on Ubuntu 18.04, and when calling the function I get the following error message:
"Invalid MEX-file '{path-to}/CCGHeart.mexa64': Undefined symbol: mxErrMsgTxt"
It is my understanding that mxErrMsgTxt is legacy code and shouldn't be used. However, in the code I downloaded, it's already commented out and replaced by mexErrMsgIdAndTxt. Am I missing something in the code?
Best,
Michael
/* CCGEngine.c /*
/* This is a bare-bones C program whos purpose is to compute
Multi-unit cross correlograms quickly. Not intended for
use on its own. It is designed to be wrapped by a MATLAB
function.
Usage - [CCG, PAIRS] = CCGEngine(TIMES, MARKS, BINSIZE, HALFBINS)
TIMES ( is the name of a binary file containing N doubles giving the spike times
MARKS is the name of a binary file containing N unsigned ints giving the spike markers. Don't use zero!
BINSIZE is a number giving the size of the ccg bins in TIMES units
HALFBINS is the number of bins to compute - so there are a total of nBins = 1+2*HALFBINS bins
These should be: double, uint32,double,uint32
NB The spikes MUST be sorted.
CCG contains unsigned ints containing the counts in each bin
It is like a 3d array, indexed by [nBins*nMarks*Mark1 + nBins*Mark2 + Bin]
PAIRS contains the spike numbers of every pair of spikes included in the ccg.
If you think this program is anal, you're right. Use the MATLAB wrapper instead.
*/
#include "mex.h"
#include "matrix.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define CHECK
#define STRLEN 10000
#define PAIRBLOCKSIZE 100000000
unsigned int *Pairs;
unsigned int PairCnt, PairSz;
void AddPair(unsigned int n1, unsigned int n2) {
unsigned int *pui;
if (PairSz==0) {
/* mexPrintf("Allocating pair memory\n"); */
Pairs = mxMalloc(PAIRBLOCKSIZE*sizeof(unsigned int));
PairSz = PAIRBLOCKSIZE;
if (!Pairs) {
/*mxErrMsgTxt("Could not allocate memory for pairs");*/
mexErrMsgIdAndTxt("someerror", "Could not allocate memory for pairs");
}
}
/* check if array is full, if so add more memory*/
if(PairCnt>=PairSz) {
/* mexPrintf("Reallocating pair memory ... ");
PairSz += PAIRBLOCKSIZE;
pui = mxRealloc(Pairs, PairSz);
mexPrintf("got %x\n", pui);
if (!pui) {
mxFree(Pairs);
mxErrMsgTxt("Could not reallocate memory for pairs");
}
Pairs = pui;
*/
/*mxErrMsgTxt("Too many pairs");*/
mexErrMsgIdAndTxt("someerror", "Too many pairs");
}
Pairs[PairCnt++] = n1;
Pairs[PairCnt++] = n2;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
unsigned int nSpikes, nMarks, HalfBins, nBins, i, CountArraySize, CountIndex;
double *Times;
double BinSize, FurthestEdge;
unsigned int *Marks, Mark, *Count;
unsigned int CenterSpike, Mark1, Mark2, Bin;
int SecondSpike; /* we want to let it go negative so we can stop it there... */
double Time1, Time2;
char errstr[STRLEN];
/* global variables are not initialized on each call to mex fn!! */
PairCnt = 0; PairSz = 0;
if (nrhs!=4) {
/*mxErrMsgTxt("Must have 4 arguments\nBut listen: You don't want to use this program.\nUse the MATLAB wrapper function CCG instead.\n");*/
mexErrMsgIdAndTxt("someerror", "Must have 4 arguments\nBut listen: You don't want to use this program.\nUse the MATLAB wrapper function CCG instead.\n");
}
if (mxGetClassID(prhs[0])!=mxDOUBLE_CLASS || mxGetClassID(prhs[1])!=mxUINT32_CLASS
|| mxGetClassID(prhs[2])!=mxDOUBLE_CLASS || mxGetClassID(prhs[3])!=mxUINT32_CLASS ) {
/*mxErrMsgTxt("Arguments are wrong type\n");*/
mexErrMsgIdAndTxt("someerror", "Arguments are wrong type\n");
}
/* get arguments */
Times = mxGetPr(prhs[0]);
Marks = (unsigned int *) mxGetPr(prhs[1]);
nSpikes = mxGetNumberOfElements(prhs[0]);
if (mxGetNumberOfElements(prhs[1])!=nSpikes) {
/*mxErrMsgTxt("Number of marks ~= number of spikes");*/
mexErrMsgIdAndTxt("someerror", "Number of marks ~= number of spikes");
}
BinSize = mxGetScalar(prhs[2]);
HalfBins = (unsigned int) mxGetScalar(prhs[3]);
/* derive other constants */
nBins = 1+2*HalfBins;
FurthestEdge = BinSize * (HalfBins + 0.5);
/* count nMarks */
nMarks = 0;
for(i=0; i<nSpikes; i++) {
Mark = Marks[i];
if (Mark>nMarks) nMarks = Mark;
if (Mark==0) {
/*mxErrMsgTxt("CCGEngine: No zeros allowed in Marks");*/
mexErrMsgIdAndTxt("someerror", "CCGEngine: No zeros allowed in Marks");
abort();
}
}
/* allocate output array */
CountArraySize = nMarks * nMarks * nBins;
plhs[0] = mxCreateNumericMatrix(CountArraySize, 1, mxUINT32_CLASS, mxREAL);
Count = (unsigned int *) mxGetPr(plhs[0]);
if (!Times || !Marks || !Count) {
/*mxErrMsgTxt("CCGEngine could not allocate memory!\n");*/
mexErrMsgIdAndTxt("someerror", "CCGEngine could not allocate memory!\n");
}
/* Now the main program .... */
for(CenterSpike=0; CenterSpike<nSpikes; CenterSpike++) {
Mark1 = Marks[CenterSpike];
Time1 = Times[CenterSpike];
/* Go back from CenterSpike */
for(SecondSpike=CenterSpike-1; SecondSpike>=0; SecondSpike--) {
Time2 = Times[SecondSpike];
/* check if we have left the interesting region */
if(fabs(Time1 - Time2) > FurthestEdge) break;
/* calculate bin */
Bin = HalfBins + (int)(floor(0.5+(Time2-Time1)/BinSize));
Mark2 = Marks[SecondSpike];
CountIndex = nBins*nMarks*(Mark1-1) + nBins*(Mark2-1) + Bin;
#ifdef CHECK
if (CountIndex<0 || CountIndex >= CountArraySize) {
sprintf(errstr, "err a: t1 %f t2 %f m1 %d m2 %d Bin %d, index %d out of bounds",
Time1, Time2, Mark1, Mark2, Bin, CountIndex);
/*mxErrMsgTxt(errstr);*/
mexErrMsgIdAndTxt("someerror", errstr);
}
#endif
/* increment count */
Count[CountIndex]++;
if (nlhs>=2) AddPair(CenterSpike, SecondSpike);
}
/* Now do the same thing going forward... */
for(SecondSpike=CenterSpike+1; SecondSpike<nSpikes; SecondSpike++) {
Time2 = Times[SecondSpike];
/* check if we have left the interesting region */
if(fabs(Time1 - Time2) >= FurthestEdge) break;
/* calculate bin */
Bin = HalfBins + (unsigned int)(floor(0.5+(Time2-Time1)/BinSize));
Mark2 = Marks[SecondSpike];
CountIndex = nBins*nMarks*(Mark1-1) + nBins*(Mark2-1) + Bin;
#ifdef CHECK
if (CountIndex<0 || CountIndex >= CountArraySize) {
sprintf(errstr, "err b: t1 %f t2 %f m1 %d m2 %d Bin %d, index %d out of bounds",
Time1, Time2, Mark1, Mark2, Bin, CountIndex);
/*mxErrMsgTxt(errstr);*/
mexErrMsgIdAndTxt("someerror", errstr);
}
#endif
/* increment count */
Count[CountIndex]++;
if (nlhs>=2) AddPair(CenterSpike, SecondSpike);
}
}
if (nlhs>=2) {
plhs[1] = mxCreateNumericMatrix(PairCnt, 1, mxUINT32_CLASS, mxREAL);
memcpy(mxGetPr(plhs[1]), (void *)Pairs, PairCnt*sizeof(unsigned int));
mxFree(Pairs);
}
/* sayonara */
}

Respuesta aceptada

James Tursa
James Tursa el 22 de Mayo de 2020
Editada: James Tursa el 22 de Mayo de 2020
All of the mxGetErrMsg references have been commented out in your posted code, so that is not the problem. I would guess that you are inadvertently running a mex routine that you downloaded ... i.e. compiled with the mxGetErrMsg references in it. Try this and see what function you are actually running:
which CCGEngine
You should get rid of the compiled mex routines you downloaded, or at least move them somewhere out of your path and out of your working directory.
  6 comentarios
Michael Hadler
Michael Hadler el 28 de Mayo de 2020
Thank you so much! I'll include it just to be sure :)
(just to be sure, I'm not fit in C: where do I include string.h?)
James Tursa
James Tursa el 28 de Mayo de 2020
In every source code file that uses a function or type defined in string.h, you need to include it before the compiler sees those functions or types. In your case, every source file that uses memset( ) or memcpy( ) needs this line, usually at the top of the file:
#include <string.h>

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Productos


Versión

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by