2009-04-20 10 views
0

私はMATLABのmex関数でマルチスレッドをテストするために実行しているコードが少しあります(MATLABはスレッドセーフではありません。私はちょうど何が起こるか見るために遊んでいる)。 MATLAB Cコード関数のエントリポイントには、ポストの一番下にあるコードにmexFunction関数のシグネチャがあります。基本的には、この関数の引数をpthreadを使って作成した別のスレッドに渡したいので、すべてを構造体に束ねる必要があります。私が変更できないmexFunctionのシグネチャには、mxArrayへのポインタの配列が含まれていますが、mxArrayへのポインタの配列を構造体定義に直接含めることはできません。配列に割り当てることはできません)。たとえば、この動作しません:constへのポインタの配列でのconstのキャストとCに関するその他の質問

typedef struct MexFunArgs { 
    int nrhs; 
    const mxArray *prhs[]; 
} MexFunArgs; 

/* ... now within the mexFunction ... */ 

MexFunArgs mfa; 

mfa.prhs = prhs; 

この問題を解決するために最初に考えたが、これに構造体の定義を変更することです:

typedef struct MexFunArgs { 
    int nrhs; 
    const mxArray **prhs; 
} MexFunArgs; 

しかし、その後、私は他のスレッドでは、この構造体を使用する場合、私はそれがmexCallMATLAB関数に渡すためにポインタの配列にキャストする必要がありますが、私が知る限り、行えません(私がここに間違っていれば私を修正してください!)。

だから、私の代わりに私がこれまでの構造の定義を変更するだろうと思った:

typedef struct MexFunArgs { 
    int nrhs; 
    const mxArray *(*prhs)[]; 
} MexFunArgs; 

すなわち、mxArrayのへのポインタの配列へのポインタ。これは代入の問題を解決します(ただし、コンパイラは理解できない理由で互換性のないポインタ型について不平を言っています)。しかし、mexCallMATLAB関数はconst mxArraysへのポインタの配列をとるのではなく、非const mxArraysへのポインタの配列を取ります。だから私はconst mxArraysへのポインタの配列に私のポインタのconstの側面をキャストする方法があるかどうかを知りたいと思います。私はそれをする方法がわかりません...以下は合法ではありません:

(mxArray *(*)[]) 

できますか?そうでない場合は、私は何をしようとしているのですか(これらの引数を他のスレッドに渡して、コンパイラがうずまきなく使用できるような方法で無傷にします)。

以下は、私が現在使用している完全なコードです。予想通りに動作しますが、コンパイル時に警告が表示されます。私は警告が嫌い、それが消えて欲しい。それが起こる正しい方法は何ですか?

#include <pthread.h> 
#include <unistd.h> 
#include <mex.h> 

typedef struct MexFunArgs { 
    int nrhs; 
    mxArray *(*prhs)[]; 
} MexFunArgs; 

void *do_thread(void *args) { 
    MexFunArgs *mfa = (MexFunArgs*) args; 

    mexCallMATLAB(0, NULL, mfa->nrhs, *mfa->prhs, "disp"); 

    pthread_exit(NULL); 
} 

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

    if (nrhs < 1) 
    mexErrMsgTxt("not enough input arguments"); 
    else 
    num = mxGetScalar(prhs[0]); 

    MexFunArgs mfa; 

    mfa.nrhs = nrhs; 
    mfa.prhs = &prhs[1]; /* <-- threads.c:29: warning: assignment from incompatible pointer type */ 

    pthread_t threads[num]; 

    int rc, t; 
    for (t = 0; t < num; t++) { 
    mexPrintf("In main: creating thread %d\n", t); 
    rc = pthread_create(&threads[t], NULL, do_thread, (void *) &mfa); 
    if (rc) 
     mexErrMsgTxt("Problem with return code from pthread_create()"); 
    } 
    return; 
} 
+0

データが多すぎます。情報が不十分です。あなたは* mexFunctionの何が好きですか?どこで、いつコンスタンスが重要か? –

+0

説明:あなたはmexFunctionを変更できないと言っています。私が尋ねるべきは、MexFunArgs構造体のデータで何をしたいのですか?いつ/どこで配列を割り振り、割り当てたいのですか?ポインタはどこでconstでなければならないのですか(mexFunctionの中にある必要はないからです)。 –

答えて

1

すべてをうまく動かす方法を見つけました。配列とポインタは関数シグネチャで同じように扱われるので、mxArray * thing []の代わりにmxArray **を使うようにmexFunctionを変更しました。配列の型にキャストする必要がないので、キャストに問題はありません(違法)。

0

私はあなたがまだそれはあまりにも指すオブジェクトのconst性対ポインタのconst性の違いを把握していないことを前提と広告の見出しに基づいて、野生の推測を取ります。

あなたを導く例については、Why does this allow promotion from (char *) to (const char *)?を参照してください。

とその他の質問の部分については、別々の質問に分割してください。それはあなたが求める答えを得るのに役立つかもしれません。

1

警告が原因

に非のポインタの配列へのポインタをmxArray S

をCONSTへのポインタの配列(名前)の割り当てでありますconst mxArray

より多くの修飾されたタイプにのみ安全に割り当てることができます。

これらは異なるタイプです。その特定の行の警告を無効にするか、キャストを使用するかどちらも危険です。

また、C99ベースのコンパイラでコンパイルする場合、mxArray宣言の構造体が空の[]で、可変長配列が宣言されています。これは、あなたの望むことですか?