Dlls mit dem C++ Builder erstellen => Problem mit Konfiguration



  • Hallo erstmal:

    Ich habe folgendes Problem:

    In meinem aktuellen Projekt will ich eine Dll erstellen. Ich habe dies getan, indem ich über den Konsolenassistenten eine Konsolenanwendung erstellt habe und dort als Typ dll ausgewählt habe. Die Dll wurde zwar erfolgreich kompiliert, allerdings kann ich auf meine Funktion in der Dll über GetProcAddress nicht zugreifen.

    Weiterhin ist mir aufgefallen, dass die Hauptfunktion der Dll DllEntryPoint heisst, und nicht, wie ich gewohnt bin, DllMain. Hat das vielleicht damit zu tun? Ich weiss nur, dass meine Dll, so wie ich sie programmiert habe, mit Visual Studio erstellt und ausgeführt werden kann, unter dem Borland C++ Builder geht das aber nicht.

    Muss ich dort eventuell etwas beachten? Ich kann ja einfach mal den Code posten, es ist nur ein Dll-Test, der ersetzt werden soll. Aber solange es nicht geht brauche ich das ja nicht zu tun.

    Ach ja ich verwende die Standartversion von Borland c++ builder 4.

    hier der code, wie er sich im visual studio ausführen lässt

    dll- header:

    #ifndef MESH_DELL
    #define MESH_DLL
    
    #include <iostream.h>
    #include <stdio.h>
    #include <windows.h>
    
    extern "C" __declspec (dllexport) void doSomething ();
    
    #endif
    

    dll-sourcecode (vc):

    #include "models.h"
    #include <stdio.h>
    #include <windows.h>
    
    #define MAXMODULE 50
    char module[MAXMODULE];
    
    extern "C" __declspec (dllexport)
    int WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void* data)
    {
            return 1;
    }
    
    void doSomething ()
    {
    
            printf ("hallo");
    
    }
    

    Kosolenanwendung:

    #include <windows.h>
    #include <iostream>
    //#include "D:\\flux\\models.h"
    
    typedef void (WINAPI* ptr_dll) ();
    
    int main (int argc, char** argv)
    {
    
    	HMODULE hdll   = 0;
    	char* ptr_module = NULL;
    
    	ptr_dll test = NULL;
    
    	ptr_module = new char [150];
    
    	hdll = ::LoadLibrary ("D:\\flux\\models\\Debug\\models.dll");
    	if (!hdll)
    	{
    
    		printf ("\tFehler beim Laden der dll\n");
    		return -1;
    
    	}
    
    	test = (ptr_dll) ::GetProcAddress ((HMODULE) hdll, "doSomething");
    	if (!test)
    	{
    		printf ("\tFehler: GetProcAddress fehlgeschlagen...\n");
    	}
    
    	test ();
    	(void)getchar ();
    	return 0;
    
    }
    


  • Schau doch mal, wie Borland deine Funktion aus der DLL exportiert.
    Normalerweise bewirkt dasa Extern "C" bei Borland im Gegensatz zu Microsoft einen Export mit führenden Unterstrich. Der Aufruf deiner Funktion würde dann also

    test = (ptr_dll) ::GetProcAddress ((HMODULE) hdll, "_doSomething");
    

    heissen.

    Man kann das sehr gut sehen, wenn man ein Tool wie 'Dependency Walker' einsetzt.



  • Danke für diese Hilfestellung nun klappt es. Du meintest mit einem _ oder? wie kann ich das denn umgehen? also es ist schon komisch. Kann man das nicht irgendwie so machen, dass es auf allen ide's die c++ benutzen läuft?

    ach noch was:

    was ist 'Dependency Walker' ???
    wie bist eigendlich darauf gekommen?

    gruß Para - und danke



  • Dependency Walker ist ein Freeware Tool, das (unter anderem) auch mit MS Visual Studio ausgeliefert wird. Ist aber Freeware und irgendwo im Netz zu haben (sorry, hab den Link vergessen, einfach mal danach suchen). Mit solch einem Tool kann man in die DLL (oder *.exe) schauen, um zu ssehen, welche anderen Dll's eingebunden sind, welche Funktionen importiert oder exportiert werden, usw.

    Umgehen lässt sich das mit dem Unterstrich meiner Erfahrung nach, wenn man beim erstellen der Dll (da kommt am Anfang immer dieser DLL- Assistent hoch) den VCL Support ausschaltet. Geht natürlich nur, wenn in der Dll keine VCL gebraucht wird. Dann kann eine DLL nach Microsoft Konventionen erzeugt werden.

    Alternativ dazu kann man auch eine Moduldefinitionsdatei *.def (such mal in der BCB Hilfe danach, Befehl EXPORTS) erzeugen, in der man die Funktionsnamen angeben kann.



  • man kann auch irgendwo bei den Compilereinstellungen den führenden '_' abschalten. Beachte auch, dass stdcall im C-Builder das ist, was cdecl in VC ist (und umgekehrt)


Anmelden zum Antworten