C++ Methoden aus DLL in C# aufrufen



  • CableGuy8419 schrieb:

    @CStoll
    Ich habe im C++ Code in verschiedenen Kombinationen getestet, bei denen ich die Übergabeparameter durch echte Werte ersetzt habe. Und es gibt immer einen Fehler, wenn ich entweder den Parameter long, oder das 2. char BinName durch einen direkten Wert ersetze. Ersetze ich das 1. oder 3. char durch einen Wert "Wert", wird keiner Fehler geworfen, selbst dann nicht, wenn ich Quatsch reinschreibe.

    Meinst du hier Fehler im Sinne von "lässt sich nicht compilieren" (wenn ja, mit welcher Meldung?) oder "stürzt ab, wenn die Funktion ausgeführt wird" (Exception, SegFault o.ä.)?

    PS

    Dravere schrieb:

    Und im übrigen:
    Bring den Typen um, welcher den gezeigten Code als C++ Code bezeichnet.

    Es ist zumindest innerhalb einer Klassen-Methode 😃 :p



  • Guten Morgen,

    @hustbaer
    Habe deinen Vorschlag umgesetzt. Die Methode wird Fehlerfrei durchlaufen, jedoch wird wieder keine Ausgabedatei erzeugt.

    @Dravere
    Die Methode gibt, warum auch immer, jedes mal eine 0 zurück, ganz egal ob in C#, C++, ob ein Fehler auftritt oder nicht.

    @CStoll
    Kompilieren gin, nur beim Aufruf der Methode wurde eine Exception geworfen. Leider weiss ich nicht mehr welche das war, und ich habe den C++ Codeteil nicht hier, sondern in der Firma. Ich glaube aber er hat wegen den Typen gemeckert a lá *"MeinString" cannot be casted to char



  • CableGuy8419 schrieb:

    Ich glaube aber er hat wegen den Typen gemeckert a lá *"MeinString" cannot be casted to char

    "Wegen Typen meckern" macht nur der Compiler. Zur Laufzeit könnte ich mir höchstens vorstellen, daß die Funktion den Parameter als Ausgabe verwenden will - das kracht normalerweise mit einem SegFault oder ähnlichem, wenn du String-Literale übergeben willst.
    (Ein String-Literal ala "Hallo" ist eigentlich ein const char* , auch wenn der Compiler es erlaubt, einen normalen char-Zeiger darauf zu verwenden - wenn du den aber verändern willst, passiert so etwas)



  • Morgen kann ich es dir sagen, wenn ich wieder in der Firma bin. Hab eben nochmal geschaut, hab aber statt dem ganzen C++ Code nur eine Headerdatei und eine Klasse als Textdatei mitgenommen.
    Ich probiere jetzt nochmal das ganze in C# mit den gegebenen Informationen und versuche zu kombinieren, irgendwie muss das Ding doch laufen.

    Danke euch allen für eure Hilfe. Mein Mittagsbier geht auf euch.



  • @Dravere:
    Danke für die Aufklärung.

    Ich hatte beim MarshalAsAttribute geguckt, und da stand default sei UnmanagedType.LPTStr, was CharSet.Auto entspricht.



  • @CStoll

    Also ich habe jetzt das ganze C++ Projekt vor mir:
    Er meckert, sobald ich bei den Übergabeparametern einen String oder die long Variable ausschreibe, statt den Variablennamen zu verwenden. Er meckert dann zur Laufzeit mit folgendem Fehler:
    Unbehandelte Ausnahme in EP4.exe (EP3.dll): 0x00000005: Access Violation

    Daraus müsste doch resultieren:
    Wenn ich schon in C++ statt den Variablennamen (wie DatName) keinen String ausschreiben kann (wie "Ich bin der Pfad"), dann dürfte man das in C# auch nicht machen, oder? Die Sache mit den Pointern ist echt ne Ecke verzwickter als ich dachte. Vor allem dann, wenn man aus der Java-Welt kommt und in C++/C# keine tiefen Kenntnisse hat...



  • Nun ich vermute, dass die Methode nun zwar fehlerfrei ausgeführt werden kann, aber keine Ausgabedatei erzeugt, da wahrscheinlich eine andere Methode zuvor ausgeführt werden muss.

    Diese andere Methode aus C++, in C# zu schreiben, ist noch komplizierter als die vorherige.
    Ich zeige euch das mal:
    Hier wird die Methode aus der DLL im C++ Code aufgerufen (relevante Auszüge):
    [cpp]
    void * objptr;
    strcpy(((CEP3 😉 objptr)->cfgFileName,cfgFileName);
    i=ISD151XX_Init(objptr,&myAppConfig);[/cpp]

    Es gibt 2 Übergabeparameter. Einen Objektpointer und ein struct.
    MyAppConfig konnte ich bereits lösen, es handelt sich dabei um ein struct, das ich 1 zu 1 im C# Code schreiben konnte. Nur was repräsentiert der objptr, das verstehe ich nicht. Könnt ihr mir bei dieser Funktion auch helfen, ich vermute dass diese Methode zuerst ausgeführt werden muss, und dann die Komprimierungsmethode von gestern.


  • Administrator

    CableGuy8419 schrieb:

    Nun ich vermute, ...

    Also in Java kannst du mit Vermutungen vielleicht noch etwas anfangen, aber bei C und C++ ist das eine ganz gefährliche Sache. Denn auch wenn etwas zu funktionieren scheint, muss dies nicht der Fall sein. In C und C++ hast du sogenanntes undefiniertes Verhalten. Da kann etwas korrekt kompilieren, das Resultat ist aber völlig undefiniert. Deshalb muss man immer genau wissen, was man eigentlich tut. Einfach ein wenig zu vermuten und auszuprobieren ist da keine gute Idee.
    Irgendwo MUSS es eine Dokumentation zu der Bibliothek geben oder zumindest jemanden, den man fragen kann. Sonst ist die Bibliothek schlicht und einfach nicht verwendbar.

    CableGuy8419 schrieb:

    Hier wird die Methode aus der DLL im C++ Code aufgerufen (relevante Auszüge):

    void * objptr;
    strcpy(((CEP3 *) objptr)->cfgFileName,cfgFileName);
    i = ISD151XX_Init(objptr,&myAppConfig);
    

    Dieser Code macht überhaupt keinen Sinn! Hast du womöglich etwas weggelassen? objptr ist ein reiner Zeiger, welcher aber nicht initialisiert wird und dadurch ins Nirvana zeigt. Da ist undefiniertes Verhalten garantiert.

    Grüssli



  • CableGuy8419 schrieb:

    @CStoll

    Also ich habe jetzt das ganze C++ Projekt vor mir:
    Er meckert, sobald ich bei den Übergabeparametern einen String oder die long Variable ausschreibe, statt den Variablennamen zu verwenden. Er meckert dann zur Laufzeit mit folgendem Fehler:
    Unbehandelte Ausnahme in EP4.exe (EP3.dll): 0x00000005: Access Violation

    Ja, das ist das, was ich dort oben skizzieren wollte - deine Funktion will den übergebenen String manipulieren, da stellt sich das Betriebssystem quer.
    Ich würde mal davon ausgehen, daß du den Parameter für deine C# Funktion als ref oder out definieren mußt, um die Änderungen mitzubekommen.

    Was von deinem ISD151XX_Init()-Beispielcode zu halten ist, hat Dravere bereits zusammengefasst.



  • Ja das sind 3 Zeilen Auszug aus einem größeren Stück Code.
    Da ich mich seit mehreren Tagen mit C++/C# und dem ganzen Quellcode beschäftige, vergisst man allzu oft, seine Fragen ausführlicher zu stellen.
    Morgen wird sich ein C++ Erfahrener zu mir gesellen, ich denke wenn er den Code vor sich liegen hat, könnte er das schneller lösen, mal sehen.

    THX für die Anteilnahme.


Anmelden zum Antworten