Funktion aus DLL aufrufen



  • Hallo zusammen!

    Bin neu hier, deshalb verzeiht mir etwaige Fehler fürs Erste 😉

    Also ich hab eine DLL mit folgendem Code. Der Code muss so sein, weil das Format von einer anderen Anwendung so benötigt wird. Nun versuche ich, diese Funktion testweise aus einem anderen C++ Programm aufzurufen, bekomme es aber nicht hin.

    MYAPI(double) add2Values(VDllFunArgVariant * arg, int argCnt);   
    
    MYAPI(double) add2Values(VDllFunArgVariant * arg, int argCnt)
    {
      double arg1= 0, arg2= 0;
    
      arg1=          arg[0].data->d;
      arg2=          arg[1].data->d;
    
      return arg1 + arg2;
    }
    

    Die DLL wird in der anderen Anwendung richtig eingebunden, aber ich finde keinen Weg, sie vernünftig aufzurufen.

    Wahrscheinlich werdet ihr mehr Infos brauchen, einfach nur sagen was genau 😉

    Danke euch schonmal!

    MYAPI und VDllFunArgVariant werden in einer externen Datei definiert:

    #ifndef IMPORT_FUNCTIONS_DLL
        #define MYAPI(ret) __declspec(dllexport) ret
      #endif
    
      typedef struct structVDllFunArgVariant { 
        VDatatypEnum   type;   // Data type 
        unsigned short yDim;   // Y-dimension (rows count)  
        unsigned short xDim;   // X-dimension (columns count) 
        TDllFunValue * data;   // Pointer to array of TDllFunValue objects 
    
      } VDllFunArgVariant;
    


  • Ich versuche zu laden ...

    Tolle Beschreibung. Vermutung: du benutzt den Funktionsnamen als String, es handelt sich aber um einen gemangelten C++ Namen. Verwende den richtigen String oder übersetze die Funktion mit extern C.



  • Bin leider neu in C++, daher kann ich mit den Infos nicht viel anfangen 😕

    Das komische ist auch, dass die Funktion in der Header-Datei gar nicht erwähnt wird, diese wird aber von der DLL eingebunden. Wahrscheinlich findet er deswegen die Funktion auch nicht.

    Weiß allerdings nicht, wie ich in der Header-Datei die Funktion richtig deklariere.



  • DerKiLLa schrieb:

    Bin leider neu in C++, daher kann ich mit den Infos nicht viel anfangen :confused

    Bin nicht neu und kann mit den Infos nichts anfangen.

    Wenn du Hilfe willst, beschreibe dein Problem detailliert.



  • Im Prinzip ist das alles, was an Code da ist in der DLL. Und ich möchte die Funktion nun aus einer anderen C++ Anwendung aufrufen. Wahrscheinlich brauche ich dazu etwas in der Header-Datei, jedoch weiß ich nicht was.



  • er meint:

    extern "C" MYAPI(double) add2Values(VDllFunArgVariant * arg, int argCnt);
    

    Damit umgehst du das C++ Namemangling.



  • Okay, hab ich in der DLL geändert. Aber jetzt fehlt noch der Aufruf aus der anderen Anwendung.

    In der anderen Anwendung ist die DLL als Verweis hinzugefügt und zusätzlich wird die Header Datei eingebunden, wie hier beschrieben: http://msdn.microsoft.com/de-de/library/ms235636.aspx

    Jetzt möchte ich also einfach die Funktion aufrufen, das Beispiel von MSDN ist:

    int main()
    {
        double a = 7.4;
        int b = 99;
    
        cout << "a + b = " <<
            MathFuncs::MyMathFuncs::Add(a, b) << endl;
        return 0;
    }
    

    Und da geht es jetzt darum, wie ich das MathFuncs::MyMathFuncs::Add ersetze.



  • Das mit dem extern brauchst du dann aber in deinem Fall nicht. Extern ist nur dann interessant, wenn du über den Namen der Funktion aus der Exporttable der DLL auf Funktionen oder Klassen zugreifen willst (WinAPI-Funktion: GetProcAddress). Du brauchst aber kein GetProcAddress, da du über das Verweisesetzen von Visual Studio implizit eine Lib mit linkst in welcher die Symbole der Funktionen aus der DLL aufgelöhst drin stehen.
    Was du also machen musst: Verweise setzen, Header einbinden - Fertig.



  • Der Header ist bereits eingebunden, nur wahrscheinlich liegt das Problem daran, dass im Header nichts über die Funktion der Quelldatei steht, da ich nicht weiß wie es in meinem Fall aussehen muss.

    In dem Beispiel von MSDN ist die Funktion in der Quelldatei ja anders aufgebaut.



  • Es ist egal, was in der Quelldatei steht. Der Compiler muss beim Kompilieren deiner EXE nur die Signatur kennen, damit der Compiler erstens weiß, wie die Funktion heißt und zweitens weiß wie die Argumente an die Funktion übergeben werden müssen. Als drittens werden die Adressen dann vom Linker richtig ersetzt. Die Adressen bekommt der Linker aus der implizit mitgelinkten Lib.

    D.h.
    Du includierst einfach deine Header in welcher die Signatur

    MYAPI(double) add2Values(VDllFunArgVariant * arg, int argCnt);
    

    steht (Verweissetzen nicht vergessen) und rufst diese auf.



  • Mr.Long schrieb:

    Es ist egal, was in der Quelldatei steht. Der Compiler muss beim Kompilieren deiner EXE nur die Signatur kennen, damit der Compiler erstens weiß, wie die Funktion heißt und zweitens weiß wie die Argumente an die Funktion übergeben werden müssen. Als drittens werden die Adressen dann vom Linker richtig ersetzt. Die Adressen bekommt der Linker aus der implizit mitgelinkten Lib.

    Wie in dem Beispiel von MSDN. Es sind zwei unterschiedliche Projekte, die aber in einer Projektmappe stecken, daher auch die Einbindung über Verweise.

    Die Headerdatei der DLL ist im Prinzip leer, bei dem Projekt gibt es keine Headerdatei, aber die Quelldatei inkludiert den (leeren) Header der DLL:

    #include "MathFuncsDll.h"
    


  • Der Compiler braucht halt beim Kompilieren deiner Exe die korrekte Signatur der Funktionen, woher er die bekommt ist kack egal.



  • Und wie würde die korrekte Signatur aussehen oder benötigst du dafür noch mehr Infos?



  • MYAPI(double) add2Values(VDllFunArgVariant * arg, int argCnt);
    


  • So, hab die korrekte Signatur nun in den Header gepackt und musste noch eine andere Header-Datei inkludieren, damit er MYAPI erkennt.

    Jetzt geht es an den Aufruf. Wie sieht der erste Parameter für die Funktion aus? Der zweite Parameter ist klar, aber beim ersten hänge ich.

    MYAPI(double) add2Values(VDllFunArgVariant * arg, int argCnt)
    
    typedef struct structVDllFunArgVariant { 
        VDatatypEnum   type;   // Data type 
        unsigned short yDim;   // Y-dimension (rows count)   
        unsigned short xDim;   // X-dimension (columns count) 
        TDllFunValue * data;   // Pointer to array of TDllFunValue objects 
    
      } VDllFunArgVariant;
    

    Wenn ich alles auf double umstelle, also die Signatur und die Funktion, dann funktioniert es schonmal. Ich muss also nun wissen, wie ich zwei Werte als ersten Parameter der Funktion übergeben kann und der zweite Paramter muss dann entsprechend die Anzahl der an Parameter 1 übergebenen Werte (=2) sein.


Log in to reply