matlab mex clang C++11线程->未定义符号错误

Posted

技术标签:

【中文标题】matlab mex clang C++11线程->未定义符号错误【英文标题】:matlab mex clang C++11 thread -> Undefined symbols error 【发布时间】:2013-06-01 03:24:11 【问题描述】:

目标:我想使用 Xcode 4.6 在 Matlab mex 文件 (R2013a) 中使用 C++11 的线程 STL

我修改了~/.matlab/R2013a/mexopts.sh

        CC='clang++'   # was llvm-gcc-4.2
        CXX='clang++'   # was llvm-g++-4.2
        MACOSX_DEPLOYMENT_TARGET='10.8'   # was 10.5. C++11 is supported >=10.7
        CXXFLAGS="$CXXFLAGS -std=gnu++11 -stdlib=libc++"   # additional flags

没有 C++11 特性的普通 mex 文件编译得很好。此外,除了链接失败之外,编译器可以很好地检测到 STL。

>> mex mextest.cpp

Undefined symbols for architecture x86_64:
"std::__1::__thread_struct::__thread_struct()", referenced from:                                      
    void* std::__1::__thread_proxy<std::__1::tuple<void (*)()> >(void*) in mextest.o                        
"std::__1::__thread_struct::~__thread_struct()", referenced from:                            
    void* std::__1::__thread_proxy<std::__1::tuple<void (*)()> >(void*) in mextest.o                        
"std::__1::__thread_local_data()", referenced from:                              
    void* std::__1::__thread_proxy<std::__1::tuple<void (*)()> >(void*) in mextest.o                      
"std::__1::__throw_system_error(int, char const*)", referenced from:                      
    _mexFunction in mextest.o                   
"std::__1::thread::join()", referenced from:                    
    _mexFunction in mextest.o                            
"std::__1::thread::~thread()", referenced from:                    
    _mexFunction in mextest.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 ' "mextest.mexmaci64"' failed.

Error using mex (line 206)
Unable to complete successfully.

实际的源代码如下所示。细节并不重要,因为它在带有 Visual Studio 2012 Express 的 Matlab R2013 WINDOWS 版本中编译得很好。使用“clang++ -std=gnu++11 -stdlib=libc++ clangtest.cpp”也可以很好地编译等效的 cpp。所以,至少,代码中没有逻辑错误(我不是说它是安全代码。这只是一个测试。)

#include "mex.h"
#include <thread>
#include <stdio.h>

int count_thread1 = 0;
int count_thread2 = 0;

void hello()

    count_thread2 = 0;
    for(int i=0; i<=10000; i++)
        for (int j=1;j<=20000;j++)
            count_thread2 = i-j-1;
        
        count_thread2++;
        printf("2: %d , %d\n", count_thread1, count_thread2); // Not sure if printf is thread-safe in Matlab. But it works in this particular example
    

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])

    count_thread1 = 0;
    std::thread t(hello);
    for (int i=1;i<=10000;i++)
    
        for (int j=1;j<=20000;j++)
            count_thread1 = -i+j-1;
        
        count_thread1++;
        mexPrintf("1: %d , %d\n", count_thread1, count_thread2);
    
    mexPrintf("\n");
    t.join();
    mexPrintf("Done\n");

看来我必须替换一些包含目录和/或库目录。应该修改哪些选项?

谢谢。

【问题讨论】:

CC='clang++' - 为什么? 【参考方案1】:

该错误是由于针对-stdlib=libc++ 编译但针对-lstdc++ 链接造成的。您可以通过以下两种方式之一修复它:

    mexopts.sh 中修复它。最激烈和最有效的解决方案。位于~/.matlab/$MATLAB_VERSION/mexopts.sh,它决定了所有编译器选项。只需将所有 stdc++ 查找/替换为 c++。

    拼凑解决方案:只需在CXXLIBS 的尾部添加-lc++。我不确定链接多个标准库版本的效果是什么,但它似乎有效。在您的 mex 调用中,添加参数 CXXLIBS="\$CXXLIBS -lc++"

作为次要问题,我相信您完全覆盖了CXXFLAGS 的值;您必须像我在上面对库所做的那样转义 $ 符号。

【讨论】:

以上是关于matlab mex clang C++11线程->未定义符号错误的主要内容,如果未能解决你的问题,请参考以下文章

Cholesky 分解的 Matlab Mex C 实现

尝试在 MatLab 中编译 C mex 文件

多线程 (pthreads) MATLAB mex 函数导致 MATLAB 在退出后崩溃

使用 mingw-w64 编译 mex 的链接器错误

使用带有 MEX Wrapper 的辅助 C 文件从 MATLAB 2016 调用 C++ 代码时遇到问题

在 MATLAB 中使用 MEX 文件访问存储在元胞数组中的矩阵