Problem beim DLL-Einbinden und GetProcAddress()

Moin!

Ich verzweifle am korrekten Einbinden einer DLL. Obwohl ich mich, denke ich, an die zahlreichen Beispiele im Internet gehalten habe, klappt es einfach nicht. Wäre nett, wenn mal jemand drüber gucken könnte.

Und bitte nicht auf Google verweisen, da habe ich nun schon etliche Stunden erfolglos investiert…

Das Einbinden per LoadLibrary() klappt, jedoch liefert GetProcAddress() kein gültiges Handle. GetLastError() liefert 127 (The specified procedure could not be found) zurück.

myDLL.h :

#ifdef MYDLL\_EXPORTS
#define MYDLL\_API \_\_declspec(dllexport)
#else
#define MYDLL\_API \_\_declspec(dllimport)
#endif

MYDLL\_API void ScreenShotWholeDesktop(void);

myDLL.cpp :

#include "stdafx.h"
#include "myDLL.h"

BOOL APIENTRY DllMain( HANDLE hModule, 
 DWORD ul\_reason\_for\_call, 
 LPVOID lpReserved
 )
{
 switch (ul\_reason\_for\_call)
 {
 case DLL\_PROCESS\_ATTACH:
 case DLL\_THREAD\_ATTACH:
 case DLL\_THREAD\_DETACH:
 case DLL\_PROCESS\_DETACH:
 break;
 }
 return TRUE;
}


MYDLL\_API void ScreenShotWholeDesktop(void) {
//--------------------------------------------------------------------------------------------------------------------------
//\_\_declspec(dllexport) void \_cdecl ScreenShotWholeDesktop(void) {
//--------------------------------------------------------------------------------------------------------------------------
 int nWidth = GetSystemMetrics(SM\_CXSCREEN);
 int nHeight = GetSystemMetrics(SM\_CYSCREEN);

 HWND hWnd = ::GetDesktopWindow();
 HDC hdc = ::GetDC(hWnd);
 HDC memDC = ::CreateCompatibleDC(hdc);
 HBITMAP hbm = ::CreateCompatibleBitmap(hdc, nWidth, nHeight);
 HBITMAP hbmOld = (HBITMAP)::SelectObject(memDC, hbm);

 ::BitBlt(memDC, 0, 0, nWidth, nHeight, hdc, 0, 0, SRCCOPY);

 BITMAPINFO bmi;

 ZeroMemory(&bmi, sizeof(bmi));

 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 bmi.bmiHeader.biWidth = nWidth;
 bmi.bmiHeader.biHeight = nHeight;
 bmi.bmiHeader.biBitCount = 24;
 bmi.bmiHeader.biPlanes = 1;
 bmi.bmiHeader.biCompression = BI\_RGB;
 bmi.bmiHeader.biSizeImage = 32 \* nWidth \* nHeight / 8;

 BYTE \*pbBits = new BYTE[bmi.bmiHeader.biSizeImage];

 ::GetDIBits( memDC, 
 hbm,
 0,
 bmi.bmiHeader.biHeight,
 pbBits,
 &bmi,
 DIB\_RGB\_COLORS );

 BITMAPFILEHEADER bfh;

 bfh.bfType = ('M' 

testDLL.cpp :


    
    #include "stdafx.h"
    #include "..\\myDLL.h"
    
    typedef void (\*DLLFUNC)(void);
    
    int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {
     //
     HMODULE hDLL = LoadLibrary("..\\debug\\myDLL.dll");
     DLLFUNC pfnDllScreenShotWholeDesktop = NULL;
     if(hDLL==NULL) {
     MessageBox(NULL,"LoadLibrary NICHT erfolgreich!",NULL,MB\_OK);
     }
    
     pfnDllScreenShotWholeDesktop = (DLLFUNC)GetProcAddress((HINSTANCE)hDLL,"ScreenShotWholeDesktop");
     if(pfnDllScreenShotWholeDesktop==NULL) {
     MessageBox(NULL,"GetProcAddress NICHT erfolgreich!",NULL,MB\_OK);
     char sTmp[10]={0};
     wsprintf(sTmp,"Error: %i",GetLastError());
     MessageBox(NULL,sTmp,NULL,MB\_OK);
     }
    
     //pfnDllScreenShotWholeDesktop();
     FreeLibrary(hDLL);
     return 0;
    }




Im Voraus schonmal vielen Dank!

Gruß Matze

Hi,

ich will nicht sagen, daß ich große Ahnung von DLL_Programmierung habe.

Also stelle ich mal eine (vielleicht dumme) Frage:

Deine DLL-Header Datei ist :

myDLL.h :

#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

MYDLL_API void ScreenShotWholeDesktop(void);

Das heißt doch, sie exportiert nur dann die Funktion korrekt, wenn
das Symbol MYDLL_EXPORTS existiert.
Zur Frage: Sollte das Symbol dann nicht irgendwann mal mit
#define MYDLL_EXPORTS“ gesetzt werden ?

Nun ja, wie gesagt meine Ahnung in dem Bereich ist begrenzt :smile:

Wünsche noch viel Erfolg,
Hendrik

Hallo!

Die von dir angesprochene Stelle ist vom VS erzeugt worden und funktioniert. Ich habe mich allerdings auch gefragt, ob das define denn auch wirklich immer definiert ist, insofern war das entweder keine dumme Frage oder wir sind beide nicht die hellsten :wink:

Ich habe den Fehler (?!) allerdings eben mithilfe eines Kollegen gefunden.
Man muss in der Header-Datei vor die Deklaration ein ‚extern „C“‘ setzen. Dies hatte ich schon vorher versucht, bin allerdings immer gescheitert. Als wir es dann nochmal mit geschweiften Klammern versuchten, hat’s geklappt.

So muss es aussehen:

extern "C" { MYDLL\_API void ScreenShotWholeDesktop(void); }

Trotzdem danke!

Gruß Matze

Hallo!

Man muss in der Header-Datei vor die Deklaration ein ‚extern
„C“‘ setzen.

Yup, sonst macht das Ding typsicheres linken und das hat mit C-Style
nichts zu tun.

So muss es aussehen:

Wenn du es ganz richtig machen willst dann gehört noch was dazu
oder besser, dann kannst du es ohne Änderungen auch in C-Quellen
benutzen.

#ifdef \_\_cplusplus
extern "C" {
#endif

/\* hier kommen jetzt alle Definitionen die C-Style sind \*/
MYDLL\_API void ScreenShotWholeDesktop(void);

#ifdef \_\_cplusplus
}
#endif

Gruß
Stefan