2009-04-20 9 views
0

Ich habe ein bisschen Code, den ich laufen lasse, um Multithreading in MATLAB mex Funktionen zu testen (Ich weiß, MATLAB ist nicht Thread sicher. Ich spiele nur herum, um zu sehen, was passiert. Der Einstiegspunkt für MATLAB C-Code-Funktionen hat die Signatur der mexFunction-Funktion in dem Code, der am unteren Ende des Posts abgeschnitten ist. Da ich die Argumente dieser Funktion im Wesentlichen in einen anderen mit pthreads erstellten Thread übergeben möchte, muss ich alles in einer Struktur zusammenfassen. Die Signatur der mexFunction (die ich nicht ändern kann) enthält ein Array von Zeigern auf mxArray, aber ich kann nicht direkt ein Array von Zeigern zu mxArray in die Strukturdefinition aufnehmen, da ich dann dieses Feld der Struktur nicht zuordnen konnte (kann keinem Array zugewiesen werden). Zum Beispiel funktioniert das nicht:Wegwerfen der Const-Ness in einem Array von Zeigern auf const und andere Fragen bezüglich C

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

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

MexFunArgs mfa; 

mfa.prhs = prhs; 

Ein erster Gedanke, dies zu beheben, ist die Strukturdefinition zu, dies zu ändern:

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

jedoch dann, wenn ich diese Struktur in dem anderen Thread verwenden , Würde ich zu einem Array von Zeigern zurückkehren müssen, um es an die mexCallMATLAB-Funktion zu übergeben, die, soweit ich weiß, nicht getan werden kann (bitte korrigieren Sie mich, wenn ich hier falsch liege!).

Also, ich dachte stattdessen würde ich die Strukturdefinition Um dies zu ändern:

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

das heißt, ein Zeiger auf ein Array von Zeigern auf mxArray. Dies löst das Zuordnungsproblem (obwohl der Compiler immer noch aus nicht nachvollziehbaren Gründen über inkompatible Zeigertypen klagt). Es stellt sich jedoch heraus, dass die Funktion mexCallMATLAB kein Array von Zeigern für const mxArrays, sondern stattdessen ein Array von Zeigern für nicht konstante mxArrays verwendet. Jetzt würde ich gerne wissen, ob es eine Möglichkeit gibt, den const-Aspekt meines Zeigers auf ein Array von Zeigern zu const mxArrays wegzuwerfen. Ich habe keine Ahnung, wie das geht ... Folgendes ist nicht zulässig:

(mxArray *(*)[]) 

Kann es getan werden? Wenn nicht, ist das, was ich versuche zu tun (diese Argumente an den anderen Thread unbeschadet zu übergeben, so dass sie ohne Compiler-Jammern benutzt werden können), die auf andere Weise in C möglich sind?

Das Folgende ist der vollständige Code, den ich momentan verwende, der wie erwartet ausgeführt wird, aber beim Kompilieren eine Warnung erzeugt. Ich hasse Warnungen und möchte, dass sie verschwindet. Was ist der richtige Weg, dies zu erreichen?

#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

Zu viele Daten, nicht genügend Informationen. Was würdest du gerne * mexFunktion machen? Wo und wann ist Konstanz wichtig? –

+0

Klarstellung: Sie sagten, Sie können die mexFunction nicht ändern. Was ich hätte fragen sollen: Was wollen Sie mit den Daten in der MexFunArgs Struktur tun? Wann/wo möchten Sie das Array zuweisen, zuweisen, usw.? Wo müssen die Zeiger const sein (da sie nicht innerhalb von mexFunction sein müssen)? –

Antwort

1

Ich habe einen Weg gefunden, alles funktioniert glücklich zu machen. Da Arrays und Zeiger in Funktionssignaturen identisch behandelt werden, habe ich nur die mexFunction geändert, um mxArray ** anstelle von mxArray * thing [] zu verwenden. Dann gibt es kein Problem beim Casting, da keine Umwandlung in einen Array-Typ (illegal) erforderlich ist.

0

Einen wilde Vermutung auf der Grundlage Ihrer Schlagzeile Ich gehe davon aus, dass Sie noch nicht den Unterschied zwischen der Konstantheit eines Zeigers gegenüber dem Konstantheit des Objekts erfaßt es auch Punkte.

Siehe Why does this allow promotion from (char *) to (const char *)? für ein Beispiel, das Sie führen kann.

Für die und andere Fragen Teil, warum teilen Sie sie in separate Fragen. Das kann helfen, die Antworten zu erhalten, die Sie suchen.

1

Die Warnung ist aufgrund Zuordnung von

einem Array (name) von Zeigern mxArray s

zu

ein Zeiger auf Arrays von Zeigern von nicht const const mxArray.

Denken Sie daran, dass Sie nur einem qualifiered Typ sicher zuweisen können.

Dies sind verschiedene Arten. Entweder du deaktivierst die Warnung für diese bestimmte Zeile oder verwendest eine Besetzung - beides gleichermaßen gefährlich.

Wenn Sie mit einem C99-basierten Compiler kompilieren, deklariert die Struktur [] der Struktur in der mxArray-Deklaration außerdem ein Array variabler Länge. Ist das was du willst?