5

目標: 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 バージョンで適切にコンパイルされるため、詳細は重要ではありません。同等の cpp も、「clang++ -std=gnu++11 -stdlib=libc++ clangtest.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");
}

一部のインクルード ディレクトリやライブラリ ディレクトリを置き換える必要があるようです。どのようなオプションを変更する必要がありますか?

ありがとうございました。

4

1 に答える 1

5

エラーは、に対してコンパイルし-stdlib=libc++ているが、に対してリンクしているため-lstdc++です。次の 2 つの方法のいずれかで修正できます。

  1. で修正しmexopts.shます。最も抜本的で効果的なソリューション。にあり~/.matlab/${MATLAB_VERSION}/mexopts.sh、すべてのコンパイラ オプションを決定します。すべてのstdc ++を見つけてc ++に置き換えるだけです。

  2. パッチワーク ソリューション:-lc++の末尾に追加するだけですCXXLIBS。標準ライブラリの複数のバージョンに対してリンクすることの効果はわかりませんが、うまくいくようです。mex 呼び出しで、引数を追加しますCXXLIBS="\$CXXLIBS -lc++"

二次的な問題として、CXXFLAGS;の値を完全に上書きしていると思います。$上記のライブラリで行ったように、シンボルをエスケープする必要があります。

于 2013-09-03T23:11:49.353 に答える