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!


Log in to reply