C++ DLL in C# verwenden - EntryPoint



  • Hallo!

    Mein Ziel ist es, Funktionen einer DLL, die ich in C++ geschrieben habe, in meinem C# Programm zu verwenden.
    Ich habe noch nie eine DLL geschrieben muss ich dazu sagen 😉
    (Ich benutze DEV C++ und Visual C# 2010).
    Die DLL kann ich erfolgreich kompilieren und mein C# programm scheint auch auf sie zugreifen zu können, es beschwert sich aber über einen fehlenden Einstiegspunkt..

    /* Replace "dll.h" with the name of your header */
    #include "dll.h"
    #include <windows.h>
    
    DllClass::DllClass()
    {
    
    }
    
    DllClass::~DllClass ()
    {
    
    }
    
    BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                           DWORD reason        /* Reason this function is being called. */ ,
                           LPVOID reserved     /* Not used. */ )
    {
        switch (reason)
        {
          case DLL_PROCESS_ATTACH:
            break;
    
          case DLL_PROCESS_DETACH:
            break;
    
          case DLL_THREAD_ATTACH:
            break;
    
          case DLL_THREAD_DETACH:
            break;
        }
    
        /* Returns TRUE on success, FALSE on failure */
        return TRUE;
    }
    
    void DllClass::testFunction1(int x, int y)
    {
         Beep(x, y);
    }
    
    #ifndef _DLL_H_
    #define _DLL_H_
    
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    
    class DLLIMPORT DllClass
    {
      public:
        DllClass();
        virtual ~DllClass(void);
    
        void testFunction1(int x, int y);
    
      private:
    
    };
    
    #endif /* _DLL_H_ */
    
    namespace DllImportTestProject
    {
        public partial class Form1 : Form
        {
            [DllImport("TestDLL.dll")]
            static extern void testFunction1(int x, int y);
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                testFunction1(500, 500); 
            }   
        }
    }
    

    Also beim Klick auf den button solls piepen.
    Ich habe schonmal in C# mit der kernel32.dll gearbeitet, das hat immer funktioniert. Daher vermute ich mal ganz stark, dass der Fehler in der DLL liegt, weswegen ich auch hier im C++ Forum poste.
    Mit der Fehlermeldung kann ich nicht wirklich etwas anfangen, da ich noch nie mit eigenen DLLs gearbeitet habe... Ich würde mich sehr über Hilfe freuen 🙂

    Viele Grüße!



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x) in das Forum Compiler- und IDE-Forum verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich hab zwar keine Ahnung von C#, was mir aber auffällt ist, dass du eine Klassen-Methode als freie Funktion aufrufst. Ich kann mir nur schwer vorstellen, dass dies möglich wird, nur weil du C# benutzt. Deklariere deine Methode als statische Methode oder noch besser, schreibe sie als freie Funktion.



  • Also bei der weiteren Recherche bin ich auf den Unterschied zwischen unmanaged und managed Code gestoßen. Die selbstprogrammierte C++ DLL enthält nehme ich an unmanaged Code.
    Daher nehme ich desweiteren an, dass das Problem die Umwandlung von unmanaged in managed code ist.
    Was ist eigentlich der Unterschied? managed gehört zu .NET und unmanaged nicht.. aber der tatsächliche Unterschied ist mir nicht klar.

    Grüße!



  • void2k11 schrieb:

    Die selbstprogrammierte C++ DLL enthält nehme ich an unmanaged Code.

    Das wird wohl so sein.

    void2k11 schrieb:

    Daher nehme ich desweiteren an, dass das Problem die Umwandlung von unmanaged in managed code ist.

    Nein, weil du auch unmanaged Code in deiner .net-Umgebung nutzen kannst.
    Dein primäres Problem wird wohl sein, dass du eine Methode ohne Instanz rufst. Mache eine freie Funktion und es sollte gehen.

    void2k11 schrieb:

    Was ist eigentlich der Unterschied? managed gehört zu .NET und unmanaged nicht.. aber der tatsächliche Unterschied ist mir nicht klar.

    Kann ich dir auch nicht sagen, ich schätze aber mal, das bezieht sich hauptsächlich auf den GC. Sollte dich also an der Stelle nicht stören. Du hast ja noch nicht mal ein Objekt. Deswegen kannst du auch keine Methode eines Objektes rufen. Was mir auch nicht so ganz klar ist, wie die Verbindung deiner Funktion in C# mit deiner DLL zustande kommt? Es müsste ja zumindest ein Hinweis existieren, dass diese Methode zu der Klasse gehört.



  • void2k11 schrieb:

    Die selbstprogrammierte C++ DLL enthält nehme ich an unmanaged Code.

    Das ist richtig.

    Daher nehme ich desweiteren an, dass das Problem die Umwandlung von unmanaged in managed code ist.

    Konkret ist das Problem: PInvoke (das ist der DllImport-Mechanismus) findet keinen geeigneten Einstiegspunkt in der DLL.

    Was ist eigentlich der Unterschied? managed gehört zu .NET und unmanaged nicht.. aber der tatsächliche Unterschied ist mir nicht klar.

    Vereinfacht gesagt: Unmanaged Code wird direkt zu Maschinencode kompiliert und managed code erst in eine Zwischensprache, hier die Intermediate Language, die dann bei der Ausführung zu Maschinencode kompiliert wird.

    Wenn man DllImport nutzt, ist es idR am einfachsten, wenn die unmanaged DLL nur über freie Funktionen verwendet wird.
    Alternativ zu PInvoke wäre noch der Aufruf der DLL über COM denkbar, dann kannst du auch ohne große Probleme Objektinstanz.methode etc schreiben 🙂 Das erfordert allerdings, dass die DLL mit regsvr32 registriert wird.



  • Hallo!

    Was meint ihr genau mit "freier Funktion"? Ich habe das so verstanden, dass die Funktion static ist und keiner Klasse angehört. Habe das dementsprechend geändert, aber es wird immer noch die noEntrypointex gefeuert.

    In der dllmain.cpp Funktion definiert und den Prototypen in die dll.h (Ist das der "header"?) und ausprobiert. Selbes Problem.
    Wie muss so ein Einstiegspunkt aussehen? Kann mir jemand verraten, in welche Klassen von C++ ich reinschauen soll?

    Grüße



  • Also DLL in Dev C++ hat bei mir nie funktioniert die wurden zwar immer geladen aber das DllMain wurde nie ausgeführt probier mal einen anderen Compiler



  • C# (DllImport) unterstützt keine Klassen aus native DLLs!

    Mach eine "einfache" Funktion in C mit einem *einfachen* Interface, dann geht es. Beachte aber auch, dass Du den Namen in einer DEF-Datei vorgeben solltest! Sonst musst Du zuerst nach dem Compilieren den Namen in der DLL rausfinden, den Du dann in C# verwenden musst!


Anmelden zum Antworten