Autor Beitrag
STBaf
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mo 10.12.07 18:37 
Hallo zusammen

ich bin zwar neu hier, habe aber sofort eine Frage bei der mir jemand hier hoffentlich weiterhelfen kann.
Und zwar gehts es, im Endeffekt, um das bestimmten einer mathematischen Darstellungsformel eines Graphen anhand einer Menge von Wertepaaren (oder allgemeinverständlich: Eine Funktionw welche anhand einer gemessenen Kurve im Diagramm einen Parametersatz für eine Formel ausspuckt). Das ganze nennt man Fit und nach der Levenberg-Marquardt Methode gemacht. Soweit alles kein Problem, die Methode dafür habe ich in C++ Code vorliegen.

Jetzt brauche ich die aber (für ein CGI in einem IIS Server) als C# Anwendung. Da man es sich ja "einfach" macht, kompiliert man also die C++ Funktion in eine DLL ein und legt diese zum Aufruf für die C# Anwendung bereit. Und eben da happert es da die LM-Methode einige "unschöne" Parameter als Übergabe erwartet, unter anderem Zeiger und Zeiger auf Funktionen. Ich hatte gehofft jemand hier kann mir vielleicht ein Tipp geben wie die korrekte DLL-Deklaration lauten muss damit die C++ Funktion aufgerufen werden kann.

Und zwar ist die C++ Funktion in der DLL prinzipiell wie folgt deklariert:

(laut Doku)
ausblenden Quelltext
1:
mrqmin(float x[], float y[], float sig[], int ndata, float a[], int ia[], int ma, float **covar, float **alpha, float *chisq, void (*funcs) (float, float [], float *, float [], int), float *alamda)					


(im C++ Quellcode, hier sind die Basisparameter wie float x[] usw. defines, daher ist die Deklaration der Doku vielleicht hilfreicher):
ausblenden Quelltext
1:
void NR::mrqmin(Vec_I_DP &x, Vec_I_DP &y, Vec_I_DP &sig, Vec_IO_DP &a, Vec_I_BOOL &ia, Mat_O_DP &covar, Mat_O_DP &alpha, DP &chisq, void funcs(const DP, Vec_I_DP &, DP &, Vec_O_DP &), DP &alamda))					


Wie man schon sieht ist hier das trickreiche der Zeiger auf eine Berechnungsfunktion (nicht weiter schlimm, das müßte per delegate gehen in C#). Mein Problem ist eher die Deklaration der Übergaben float **alpha sowie float ** covar, diese sind zweidimensionale Arrays welche zur Verfügung zu stellen sind für die DLL als "Speicher" zum berechnen von Werten (die Levenberg-Marquardt Methode funktioniert iterativ, ich nehme mal an er benutzt die Arrays als Ablage intern, laut Doku steht hierzu folgendes: "The arrays covar[1..ma][1..ma], alpha[1..ma][1..ma] are used as working space during most iterations.".


Hierzu habe ich mir dann mal folgende C# Klasse als Import gedacht, allerdings habe ich das Problem das ich nicht wirklich weiss wie ich diese covar und alpha Arbeitsarrays sauber deklarieren soll zur übergabe:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
  
public class DllImports
  {
          
    public delegate double UebergabeFunk(double i);
    
    [DllImport("NR.dll", EntryPoint="?fnNR@@YAHXZ")]
    public static extern int fnNr();
    
    [DllImport("NR.dll", EntryPoint="?mrqmin@NR@@YAXABV?$NRVec@N@@00AAV2@ABV?$NRVec@_N@@AAV?$NRMat@N@@3AANP6AXN041@Z4@Z")]
    public unsafe static extern void mrqmin(float[] x, float[] y, float[] sig, int ndata, float[] a, int[] ia, int ma, float[][]* covar, float[][]* alpha, float* chisq, UebergabeFunk func, float* alambda);
    //public static extern void mrqmin(Vec_I_DP &x, Vec_I_DP &y, Vec_I_DP &sig, Vec_IO_DP &a, Vec_I_BOOL &ia, Mat_O_DP &covar, Mat_O_DP &alpha, DP &chisq, void funcs(const DP, Vec_I_DP &, DP &, Vec_O_DP &), DP &alamda);
    
    public DllImports()
    {

    }
    
    public unsafe void fit(float[] x, float[] y, float[] sig, int ndata, float[] a, int[] ia, int ma, float[][] covar, float[][] alpha, float chisq, float alambda)
    {
      UebergabeFunk Uebergabe = new UebergabeFunk(this.EI);
      DllImports.mrqmin(x,y,sig,ndata,a,ia,ma,&covar,&alpha,&chisq, Uebergabe, &alambda);
    }
    
    public double EI(double i)
    {
      return 0;
    }    
  }


Wenn jemand einen Tipp oder Hinweis hat wäre das prima :-)

Danke für jede Hilfe

Andre
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 10.12.07 19:12 
Keine Ahnung, ob das dann auf der C++-Seite so passt und vom Marshaller überhaupt akzeptiert wird, aber ein einfaches "float[][]" Jagged-Array sollte doch schon so ein gesuchter doppelter Zeiger sein. Und per ref/out solltest du die übrigen Sternlein auch vermeiden können.