[C++/C#] COM Interop

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

[C++/C#] COM Interop

Beitrag von Psycho »

Hallo.

Ich benutze eine fremde DLL, die in C# geschrieben wurde und möchte Werte mit einer Funktion in dieser DLL berechnen.
Also habe ich eine neue DLL in C# geschrieben, die auf die originale zugreift und meiner C++-Anwendung als Proxy dient.
So wie hier.

Nun ist es so, dass es ungefähr so aussieht:

Code: Alles auswählen

[Guid("C6659361-1625-4746-931C-36014B146679")]
public class InterfaceImplementation : IManagedInterface
{
   public int PrintHi()
   {
      FremdeKlasse instanz = new FremdeKlasse();
      /* Diese FremdeKlasse nutzt intern statische private Member, die unter anderem checken,
      ob bereits ca. 300MB Daten in dem RAM entzippt wurden.
      Das möchte ich nur einmal machen, da dass einige Sekunden in Anspruch nimmt und
      ich die Funktion gerne schnell und öfters aufrufen möchte. */
      float[] meineParameter = { 0.0f, 0.2f, 0.5f };
      instanz.berechne(meineParameter);
      // Berechne nochmal, um zu prüfen, ob es schnell geht :)
      instanz.berechne(meineParameter);

      return 33;
   }
}
Dieser Code funktioniert tadellos. berechne() wird zweimal schnell hintereinander aufgerufen.
Jetzt kommts: Änder ich die Funktion wie folgt:

Code: Alles auswählen

   public int PrintHi(float[] meineParameter)
   {
      FremdeKlasse instanz = new FremdeKlasse();
      instanz.berechne(meineParameter);
      instanz.berechne(meineParameter);

      return 33;
   }
geht es auf einmal langsam. Das heisst FremdeKlasse() entzippt die Daten im Konstruktor und jeweils bei beiden berechne() aufrufen neu! Das ist natürlich Quatsch. Aber es hat sich ja auch etwas verändert: Ich übergebe die Parameter jetzt auch tatsächlich als Parameter der Funktion printHi().

In meinem C++-Programm wird mir dann angezeigt, die Methode hat den Parameter SAFEARRAY *.
Gut, denk ich mir, habe ein SafeArrayCreate() vom Typ VT_R4 erstellt und mit SafeArrayPutElement() befüllt.
Der Compiler beklagt sich nicht, die floats kommen in meiner Proxy-DLL auch richtig an.

Die Ausgabewerte der Methode berechne() sind auch korrekt, trotzdem dauerts halt ewig aufgrund...tja, weswegen eigentlich?
Ich habe bereits probiert, das float-Array in der printHi() Methode durch copyTo() zu kopieren, das ändert aber leider nichts.
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: [C++/C#] COM Interop

Beitrag von odenter »

Also es geht angeblich schnell wenn die Parameter in der Funktion gesetzt werden und nicht der Funktion übergeben werden?
Vermutlich werden die Aufrufe einfach weg optimiert, weil zwar eine Instanz einer Klasse erzeugt wird, auch eine Methode darauf gerufen wird, aber diese ansonsten überhaupt nicht verwendet wird. Das return 33 kann der compiler auch fix an der Stelle des Methoden aufrufes einsetzen.

Vielleicht kann der Code nicht mehr so optimiert werden, wenn die Parameter ebenfalls als Methoden-Parameter übergeben werden. Hat vielleicht was mit der Tiefe zu tun, keine Ahnung.
Wäre für mich jedenfalls die plausibelste Erklärung, warum es mal schnell geht und mal nicht. Beim ersten mal ist einfach nichts passiert.
Gib mal die berechneten Werte im ersten Code-Beispiel aus und gucke ob es dann immernoch schnell geht.
Antworten