2010-06-21 8 views
6

Ich habe die Aufgabe gegeben, einige Bibliotheksroutinen auf C# zu portieren, damit unsere anderen Anwendungsentwickler darauf zugreifen können, aber ich weiß nicht, wie man die Variablen deklariert, damit sie in die Routine kommen korrekt.Dll Importieren von C++ zu C# mit Arrays

Das Problem ist, wenn ich mit dem C++ Code in das Eingabe Lesen, erhalte ich alle schiefen Werte

Versuch zu verwenden, Schritt für Schritt durch:

double[] Par = { 8, 16, 8, 0.61, 0.00635, ... }; // 29 variables 
double[] Inlet = { 22.18, 43.31, 1.13, 2.81, 0.43 }; // 5 variables 
double[] Outlet = { 0, 0, 0, 0, 0, 0 }; // placeholder for 6 variables 
SteadyFor(ref Par, ref Inlet, ref Outlet, FileIn, FileOut); 

Die DLL-Import

[DllImport(MODELAPP, EntryPoint = "SteadyFor", ExactSpelling = false)] 
public static extern int SteadyFor(
    ref double[] par, ref double[] inlet, ref double[] outlet, 
    [MarshalAs(UnmanagedType.LPStr)] string input, 
    [MarshalAs(UnmanagedType.LPStr)] string output); 

Die C++ Datei:

extern "C" int SteadyFor(double Par[], double Inlet[], double Outlet[], char* FileIn, char* FileOut) 
{ 
    int n = (int)Par[0]; // Actual Reading: [0] 
    int nt = (int)Par[1]; // Actual Reading: [0] 
    int pass = (int)Par[2]; // Actual Reading: [0] 
    double l = Par[3]; // Actual Reading: [2.9581223236733198e+174] 
    double rTube = Par[4]; // Actual Reading: [2.121995790965e-314#DEN] 
    double tTube = Par[5]; // Actual Reading: [5.432309224896e-312#DEN] 
    double pl = Par[6]; // Actual Reading: [1.0253217546256438e-267] 
    double pt = Par[7]; // Actual Reading: [4.60629e-308] 
    // ... 
} 

Offensichtlich sind die Werte, die ich bekomme, alle falsch - fast wie nicht initialisiertes Gedächtnis.

Kann mir jemand sagen, was ich falsch mache und wie ich es beheben kann?

Grüße,

~ Joe

Antwort

7

Drop the "ref" keywords in der Erklärung, sie sind nicht korrekt. Dass der C++ Code nicht mit einem AV abstürzt, ist ein bisschen mysteriös.

Das Attribut [MarshalAs] für die Zeichenfolgen ist nicht erforderlich.

+0

Das hat funktioniert, Hans. Jetzt, warum? C++ bringt Zeiger und C# passiert ... was? Zeiger? – jp2code

+4

Das Standard-Marshalling für ein Array übergibt einen Zeiger an sein erstes Element. So wie C++ es tut. Arrays werden niemals nach Wert weitergegeben, das wäre furchtbar teuer und zum Scheitern auf großen Arrays verdammt. Wenn Sie "ref" verwenden, wird ein Zeiger auf diesen Zeiger übergeben. –

1

Grundsätzlich benötigen Sie ein Rangier-Attribut zu deklarieren. In Ihrem Fall wäre es ein MarshalAs (UnmanagedType.LPArray) Attribut.

Schauen Sie hier:
http://msdn.microsoft.com/en-us/library/z6cfh6e6%28VS.80%29.aspx#cpcondefaultmarshalingforarraysanchor3

+0

Unser Proxy bei der Arbeit kann die MSDN-Sites nicht analysieren. Ich werde später darauf eingehen. Fürs Erste werde ich nur mit deiner Antwort codieren! Vielen Dank. – jp2code

+0

@ jp2code, ich hoffe, dass Ihre lokal installierte MSDN funktioniert ...! – code4life

+0

Ratten. Das hat nicht funktioniert. Alle Werte kommen immer noch mit Ganzzahlen, wobei Nullen und Doppelungen etwas Freakiges sind. – jp2code