从Matlab文件中读取数据到C语言

8

我正在尝试学习如何使用C API读取Matlab的.mat文件,但结果并不如我预期:

我想打开一个非常简单的.mat文件,名为test.mat,从文件中读取一个值并将其存储在C变量中。我已经在Matlab中使用以下命令创建了test.mat

> value = 3;
> save ("test.mat", "value")

以下是我的 C 代码,甚至无法编译 - 编译器似乎找不到头文件。请查看下面的代码以获取编译器输出。这里出了什么问题吗? 代码:
#include <stdlib.h>
#include <stdio.h>
#include <mat.h>
#include <matrix.h>

int main(int argc, char *argv[]) {
    double value;
    MATFile *datafile;
    datafile = matOpen("test.mat", "r");

    mxArray *mxValue;
    mxValue = matGetVariable(datafile, "value");

    matClose(datafile);
    value = *mxGetPr(mxArray);

    mxFree(mxArray);

    printf("The value fetched from the .mat file was: %f", value);

    return 0;
}

编译器输出:

$ make animate_shot
cc  -I/usr/local/MATLAB/R2011a/extern/include/   animate_shot.c   -o animate_shot
/tmp/cczrh1vT.o: In function `main':
animate_shot.c:(.text+0x1a): undefined reference to `matOpen'
animate_shot.c:(.text+0x2f): undefined reference to `matGetVariable'
animate_shot.c:(.text+0x3f): undefined reference to `matClose'
animate_shot.c:(.text+0x4b): undefined reference to `mxGetPr'
animate_shot.c:(.text+0x5e): undefined reference to `mxFree'
collect2: ld returned 1 exit status
make: *** [animate_shot] Error 1

(在我的makefile中,使用了-I标志并指定了以下行:CPPFLAGS=-I/usr/local/MATLAB/R2011a/extern/include/,我已验证该目录存在并包含头文件mat.hmatrix.h)。 更新:
我发现需要链接的库是libmat.solibmx.so(根据这篇MathWorks帮助文章),它们位于系统上的/usr/local/MATLAB/R2011a/bin/glnxa64/下。因此,我已将我的makefile更新为以下内容:
CPPFLAGS =-I/usr/local/MATLAB/R2011a/extern/include/
LDFLAGS = -L/usr/local/MATLAB/R2011a/bin/glnxa64 -l mat -l mx

现在,运行make将会得到以下命令:
cc  -I/usr/local/MATLAB/R2011a/extern/include/ -L/usr/local/MATLAB/R2011a/bin/glnxa64 -l mat -l mx  animate_shot.c   -o animate_shot

然而,我仍然收到相同的错误。有任何想法吗?
1个回答

7
这是一个链接器失败,而不是编译器失败(与-I编译器选项无关)。您需要使用-L标志指定存储matlab .so文件的目录,并在编译器命令的末尾添加-l<matlab-lib-name>选项,指定matlab库的名称。
例如:

cc -I/usr/local/MATLAB/R2011a/extern/include/ -L/usr/local/MATLAB/R2011a/lib animate_shot.c -o animate_shot -lmatlab

(我不知道.so文件所在的确切目录或matlab库的名称)
基于提供更多信息的评论:

cc -I/usr/local/MATLAB/R2011a/extern/include/ -L/usr/local/MATLAB/R2011a/bin/glnxa64 animate_shot.c -o animate_shot -lmat -lmx


@TomasLycken,你在“-l”和“mat”之间有空格吗?如果有,请将其删除:“-lmat -lmx”。不确定这是否重要,但Sun Forte编译器的帮助(我认为你正在使用)没有显示空格。 - hmjd
去掉空格,不会影响错误。我正在运行Ubuntu 12.04,所以我认为我正在使用GCC编译器。cc --version给出的是cc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3和版权声明。 - Tomas Aschan
1
@TomasLycken,-l选项需要在编译器命令的_末尾_(请参见此答案以了解原因:https://dev59.com/OWkw5IYBdhLWcg3wVpFi#9966989)。 - hmjd
-l*标志移到末尾解决了这个问题,但编译器抱怨找不到libmat.so的依赖项。添加-Wl,-rpath /usr/local/MATLAB/R2011a/bin/glnxa64标志也起到了作用 - 现在我的程序可以编译和运行(虽然会出现段错误;))!非常感谢! - Tomas Aschan
@TomasLycken,没问题。祝你解决段错误的问题好运。 - hmjd
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接