DLL-Funktion per VBA ansprechen - Excel wird beendet



  • Hallo liebe C++-Community,

    ich stehe vor einem eigenartigen Problem. Ich habe mir eine ziemlich umfangreiche Funktion (Eingabe mehrere Stringkette, Ausgabe eine Stringkette) im Visual C++ 2008 zusammengebastelt. Wenn ich sie mit Testdaten füttere und debugge, wird das richtige Ergebnis ausgegeben. Diese Funktion habe ich nun in ein neues Projekt kopiert und in eine DLL umgewandelt.

    Wenn ich diese Funktion im VBA aufrufe bekomme ich die Fehlermeldung:

    "Microsoft Office Excel hat ein Problem festgestellt und muss beendet werden."

    In die selbe DLL habe ich nun auch eine Testfunktion eingebaut, die wie folgt aussieht:

    extern "C" int __stdcall testfunktion(int x)
    {	
    
    	x=x+1;
    	cout << x;
    	return x;
    };
    

    in VBA spreche ich die Funktion so an:

    Private Declare Function testfunktion Lib "C:\Documents and Settings\schreima\Desktop\Planungsbord\Debug\Planungsbord.dll" (ByVal x As Integer) As Integer
    
    Sub test2()
    
        x = 1
    
        x = testfunktion(x)
    
        MsgBox x
    
    End Sub
    

    Das klappt ohne Probleme. Wie kann ich herausfinden, warum mir Excel ständig abschmiert, wenn ich die Hauptfunktion aufrufe bzw. weiß vielleicht jemand woran das liegen könnte?

    Danke für eure Hilfe

    Liebe Grüße



  • Wenn ich Dich richtig verstanden habe, hast Du die Testfunktion für die dll in der dll liegen. Das sollte nicht sein. Schreib die Testfunktion in ein eigenes main(). Hast Du auch an folgendes Konstrukt gedacht?

    // Der folgende ifdef-Block zeigt die Standardlösung zur Erstellung von Makros, die das Exportieren 
    // aus einer DLL vereinfachen. Alle Dateien in dieser DLL wurden mit dem in der Befehlszeile definierten
    // Symbol HTML_EXPORTS kompiliert. Dieses Symbol sollte für kein Projekt definiert werden, das
    // diese DLL verwendet. Auf diese Weise betrachtet jedes andere Projekt, dessen Quellcodedateien diese Datei 
    // einbeziehen, HTML_API-Funktionen als aus einer DLL importiert, während diese DLL mit diesem 
    // Makro definierte Symbole als exportiert betrachtet.
    
    #ifdef MY_DLL_EXPORTS
    #define MY_DLL_API		__declspec(dllexport)
    #else
    #define MY_DLL_API		__declspec(dllimport)
    #endif
    

    tschüß
    Troll.Soft



  • Hallo,

    Danke für die schnelle Antwort. Die Testfunktion kann ich ohne Probleme aufrufen, jedoch liefert mir Excel diese Fehlermeldung, wenn ich eine andere Funktion aufrufen, die wesentlich länger ist (mehrere Stringketten zu einer Stringkette umgewandelt und dazwischen noch einige Male manipuliert).

    Wie bekomme ich die Ursache für diesen Absturz heraus. Wie ich eine Funktion einer DLL in VBA aufrufe habe ich nur durch Zufall herausgefunden, aber ohne dem Wissen wie und warum. Ich nutze Visual Studio c++ 2008. Vielleicht habe ich Fehler bei der Erstellung der DLL gemacht, aber ich verstehe nicht, warum ich eine Funktion aufrufen kann und die andere nicht, obwohl ich für beide die selben Einstellungen vorgenommen habe.

    Wo muss ich diesen Code einfügen:

    #ifdef MY_DLL_EXPORTS 
    #define MY_DLL_API        __declspec(dllexport) 
    #else 
    #define MY_DLL_API        __declspec(dllimport) 
    #endif
    

    und was muss ich sonst noch beachten für den DLL Aufruf in VBA? Wie kann ich schrittweise Debuggen sowohl auf Seite der DLL als auch auf Seite von VBA?.

    Danke nochmals



  • Der Code gehört in den Header der dll.

    #ifdef MY_DLL_EXPORTS 
    #define MY_DLL_API        __declspec(dllexport) 
    #else 
    #define MY_DLL_API        __declspec(dllimport) 
    #endif
    
    class  MY_DLL_API   myClass  ...
    

    Das puzzige Codestück muß in der dll ganz oben in allen Headern eingebunden werden, die ihre Klassen, Funktionen exportieren wollen.
    MY_DLL_EXPORTS muß in der dll definiert sein und im main undef sein.
    Teste Deine c++ dll unbedingt mit einem c++ main. Wenn alles ok, dann weiter mit VB.

    tschüß
    Troll.Soft



  • schreima schrieb:

    und was muss ich sonst noch beachten für den DLL Aufruf in VBA? Wie kann ich schrittweise Debuggen sowohl auf Seite der DLL als auch auf Seite von VBA?.

    In den Projekteinstellungen "Debugging" gibts du Command (excel), Command arguments(sheet) und Working Dir an.
    Hier etwa in der Mitte der Seite gezeigt:
    http://www.doxapp.com/code/excel-dll.html



  • Hallo,

    ich habe das jetzt ausprobiert, jedoch bekomme ich die Fehlermeldung, dass für Excel.exe keine Debuginformationen bereitstehen.

    Aber die DLL kann ich ohne Probleme ansprechen und weiß auch schon wie und welche Einstellungen notwendig sind. Habe mir hierzu zwei Testfunktionen zusammengebastelt:

    Die Projektmappe heißt SimpleMath

    im header steht:

    #ifdef SimpleMath_EXPORTS
    #define SimpleMath_API __declspec(dllexport)
    #else
    #define SimpleMath_API __declspec(dllimport)
    #endif
    

    im main.cpp steht:

    #include <iostream>
    #include <string>
    
    __declspec (dllexport) int sum (int x)
    {
    	x=x+1;
    	return x;
    
    }
    __declspec (dllexport) std::string test (std::string y)
    {
    
    	return y;
    
    }
    

    und in der export.def steht:

    LIBRARY SimpleMath
    EXPORTS
    sum @1
    test @2
    

    in VBA spreche ich die Funktionen so an:

    Declare Function test Lib "C:\Documents and Settings\schreima\Desktop\SimpleMath\Debug\SimpleMath.dll" (ByVal x As String) As String
    Declare Function sum Lib "C:\Documents and Settings\schreima\Desktop\SimpleMath\Debug\SimpleMath.dll" (ByVal x As Integer) As Integer
    
    Sub test3()
    
    Dim x As String
    
    x = Trim("Hallo")
    
    x = test(x)
    
    MsgBox x
    
    End Sub
    
    Sub test1()
    
    x = 1
    
    x = sum(x)
    
    MsgBox x
    
    End Sub
    

    Die Funktion "sum" funktioniert, beim Aufruf der Funktion "test" bekomme ich die Fehlermeldung, dass die DLL-Aufrufkonvention falsch ist.

    Kann es sein, dass die Strings in VBA anders sind als in C++? Wie muss ich Strings aufbereiten, um sie von VBA in die C++ DLL zu schicken und retour?

    Danke für eure Hilfe



  • Visual Basic kennt kein std::string . Für dll-Interfaces ist es ganz allgemein besser, C-String zu benutzen.
    Hier mal eine Anleitung zum Hin- und Herreichen von Strings zwischen C und VB.


Anmelden zum Antworten