Niedziałająca funkcja wczytywana z DLL

0

Panowie, jesli mielibyście czas możecie sprawdzić dllkę oraz plik którym ją sprawdzam czy działa, a nastepnie wytknąć mi błąd prze który okno mi nie wyskakuje? Prawdopodobnie coś pogrzałem z wczytywaniem adresu ale nie jestem pewien. W ogóle nie wiem co jest nie tak. Pliki w załączniku

1

Lepiej wklej samą funkcję oraz miejsce jej wywołania, bezpośrednio.
Nie chcę mi się ściągać zip, rozpakowywać itp, może inni też mają mistrzowski poziom lenistwa.

0

Projekt DLL:

main.h

HWND DLL_EXPORT f_CreateButton(HINSTANCE hInstance, HWND hParent, char *sciezka, COLORREF cTransparent, int x, int y, int width, int height, int ID, DWORD flags, HRGN hRegion, void *dane); 

main.cpp

HWND DLL_EXPORT f_CreateButton(HINSTANCE hInstance, HWND hParent, char *sciezka, COLORREF cTransparent, int x, int y, int width, int height, int ID, DWORD flags, HRGN hRegion, void *dane){} 

Projekt test:

button.h

 
#include <windows.h>

#define MC_MOUSEMOVE                1
#define MC_LBDOWN                   2
#define MC_LBUP                     4
#define MC_RBDOWN                   8
#define MC_RBUP                     16
#define MC_DBCLICK                  32

#define BUTTON_STYLE_LostCapture           1
#define BUTTON_STYLE_RegionCircle          2
#define BUTTON_STYLE_MyRegion              4
#define BUTTON_STYLE_SendMouseCommand      8

#define BUTTON_STAN_AKTYWNY    0
#define BUTTON_STAN_NAJECHANY  1
#define BUTTON_STAN_WCISNIETY  2
#define BUTTON_STAN_NIEAKTYWNY 3

#define BUTTON__GETID             0x8001 /// wParam == & int
#define BUTTON__GETDATA           0x8002 /// wParam == & void
#define BUTTON__SETDATA           0x8003 /// wParam == void *     /// lParam == & void (stare dane)
#define BUTTON__GETFOCUS          0x8004 /// wParam == & int
#define BUTTON__SETFOCUS          0x8005 /// wParam == int
#define BUTTON__GETXY             0x8006 /// wParam == & POINT
#define BUTTON__GETWIDTH          0x8007 /// wParam == & int
#define BUTTON__GETHEIGHT         0x8008 /// wParam == & int
#define BUTTON__GETCAPTURE        0x8009 /// wParam == & bool

typedef BOOL( *RejestrujButton )( HINSTANCE );
RejestrujButton f_RejestrujButton;
typedef HWND( *CreateButton )( HINSTANCE, HWND, char*, COLORREF, int, int, int, int, int, DWORD, HRGN, void*);
CreateButton f_CreateButton;

HINSTANCE InitializeButton(HINSTANCE hInstance, LPCSTR sciezka){
    HINSTANCE hDll = LoadLibrary( sciezka );
    if(!hDll)
     return 0;
    f_RejestrujButton = (RejestrujButton)GetProcAddress( hDll, "f_RejestrujButton" );
    f_CreateButton = (CreateButton)GetProcAddress( hDll, "f_CreateButton" );

    f_RejestrujButton(hInstance);
    return hDll;
}

main.cpp

 
hDll = InitializeButton(hThisInstance, "static buttons");
    if(!hDll)
    {
        MessageBox(0, "blad", "", MB_OK);
        return 0;
    }
    hPrzycisk = (HWND)(CreateButton)(hThisInstance,hwnd,"LEWO.bmp",RGB(0,0,0),0,0,50,50,100, 0, NULL,NULL);
0

Pod czym kompilujesz i jak u ciebie zadeklarowane to DLL_EXPORT?

0
 
#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

Uzywam środowiska codeblock z wbudowanym kompilatorem mingw.

EDIT:
Wybaczcie, że wcześniej tego nie zrobiłem ale chyba w nocy juz nie myślałem. Wyskoczyły mi warningi, których nie potrafię zinterpretować:

||=== Build: Release in test (compiler: GNU GCC Compiler) ===|
C:\Users\User\Desktop\test\main.cpp||In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':|
C:\Users\User\Desktop\test\main.cpp|71|warning: left operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|72|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|74|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|75|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|76|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|77|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|78|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|79|warning: right operand of comma operator has no effect [-Wunused-value]|
||=== Build finished: 0 error(s), 8 warning(s) (0 minute(s), 0 second(s)) ===|

0

Czy masz zadeklarowane to BUILD_DLL przy budowie DLL?
Proste sprawdzenie, dodajesz kod do DLL:

#ifndef BUILD_DLL
    #error To ma się nie skompilować bo brak __declspec(dllexport)
#endif
0

To jest moje całe main.h z dll

 
#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

/*  To use this exported function of dll, include this header
 *  in your project.
 */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

/*



*/

#ifdef __cplusplus
extern "C"
{
#endif

#define ERR_PUSTYWSKAZNIK 1

#define STYLE_LostCapture           1
#define STYLE_RegionCircle          2
#define STYLE_MyRegion              4
#define STYLE_SendMouseCommand      8

#define MC_MOUSEMOVE                1
#define MC_LBDOWN                   2
#define MC_LBUP                     4
#define MC_RBDOWN                   8
#define MC_RBUP                     16
#define MC_DBCLICK                  32

#define STAN_AKTYWNY    0
#define STAN_NAJECHANY  1
#define STAN_WCISNIETY  2
#define STAN_NIEAKTYWNY 3

#define WH_BT_GETID             0x8001 /// wParam == & int
#define WH_BT_GETDATA           0x8002 /// wParam == & void
#define WH_BT_SETDATA           0x8003 /// wParam == void *     /// lParam == & void (stare dane)
#define WH_BT_GETFOCUS          0x8004 /// wParam == & int
#define WH_BT_SETFOCUS          0x8005 /// wParam == int
#define WH_BT_GETXY             0x8006 /// wParam == & POINT
#define WH_BT_GETWIDTH          0x8007 /// wParam == & int
#define WH_BT_GETHEIGHT         0x8008 /// wParam == & int
#define WH_BT_GETCAPTURE        0x8009 /// wParam == & bool

void DLL_EXPORT ShowError(int ID);

struct DLL_EXPORT sButtonInfo{
    HWND hwnd;
    POINT cur;
    int message;
};
struct DLL_EXPORT sButtonClassInfo{
    HINSTANCE hInstance;
    HWND hWindow;
    HRGN hRegion;

    HBITMAP hBitmap;
    COLORREF cTransparent;

    DWORD flagi;

    void *dane;
};
class DLL_EXPORT sButtonClass{
    public:
        sButtonClass(struct sButtonClassInfo *wsk);
        ~sButtonClass();

        HDC GiveMeSourceDC();
        HDC GiveMeMaskSourceDC();

        int GetStan();
        void SetStan(int Stan);
        bool GetCapture();
        void SetCapture(bool Capture);
        DWORD GetFlags();

        int BitmapWidth();
        int BitmapHeight();
        int WindowWidth();
        int WindowHeight();
        void OdswiezOkno();
        void WyslijWiadomoscDoParenta(UINT message, WPARAM wParam, LPARAM lParam);
        bool KursorWewnatrz();
        void WypelnijButtonInfo(struct sButtonInfo *wsk, HWND hwnd, int x, int y, int message);
        void GetCoordinate(POINT *point);

        int GetID();
        void SetDane(void *Dane);
        void *GetDane();
    private:
        HINSTANCE hInstance;
        HWND hWindow;
        HWND hParent;
        HRGN hRegion;

        DWORD flagi;

        int nasycenie;
        COLORREF cTransparent;

        HBITMAP hBmpSource;
        HDC hDCSource;
        HBITMAP hBmpSourceMask;
        HDC hDCSourceMask;

        int dlugosc_bitmapy;
        int wysokosc_bitmapy;

        bool capture;
        int stan;

        void *dane;

        HBITMAP CreateBitmapMask( HBITMAP hbmColour, COLORREF crTransparent );
};


LRESULT CALLBACK DLL_EXPORT ButtonProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

BOOL DLL_EXPORT f_RejestrujButton( HINSTANCE hInst );
HWND DLL_EXPORT f_CreateButton(HINSTANCE hInstance, HWND hParent, char *sciezka, COLORREF cTransparent, int x, int y, int width, int height, int ID, DWORD flags, HRGN hRegion, void *dane);

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__

Nie ma tam wzmianki o tym :(

EDIT:
Posprawdzałem, czy dll się wczytuje poprawnie i czy wskaźniki na adresy funkcji nie są zerowe i niby wszystko jest w porządku.
Zastanawiam się tylko skąd te warningi (pochodzą z wywołania funkcji CreateButton())

 
hPrzycisk = (HWND)(CreateButton)(
                                     hThisInstance, /// hInstance
                                     hwnd,          /// hParent
                                     "LEWO.bmp",    /// sciezka do bmp
                                     RGB(0,0,0),    /// cTransparent
                                     0,             /// x
                                     0,             /// y
                                     50,            /// width
                                     50,            /// height
                                     100,           /// ID
                                     0,             /// flags
                                     NULL,          /// hRegion
                                     NULL           /// hDane
                                    );

EDIT2:
Dodałem w dll w funkcji CreateButton() MessageBox'a, niestety przy wywołaniu funkcji nie pokazuje sie on, czyli funkcja w ogóle nie startuje :(

1

KUTFA MAM !

 
typedef BOOL( *RejestrujButton )( HINSTANCE );
RejestrujButton f_RejestrujButton;
typedef HWND( *CreateButton )( HINSTANCE, HWND, char*, COLORREF, int, int, int, int, int, DWORD, HRGN, void*);
CreateButton f_CreateButton;

oraz:

hPrzycisk = (HWND)(CreateButton)(
                                     hThisInstance, /// hInstance
                                     hwnd,          /// hParent
                                     "LEWO.bmp",    /// sciezka do bmp
                                     RGB(0,0,0),    /// cTransparent
                                     0,             /// x
                                     0,             /// y
                                     50,            /// width
                                     50,            /// height
                                     100,           /// ID
                                     0,             /// flags
                                     NULL,          /// hRegion
                                     NULL           /// hDane
                                    ); 

Zamiast CreateButton() powinno być f_CreateButton(). Cały dzień stracony przez to xd
Ale bez Ciebie bym nawet nie spojrzał na to, Twój ostatni komentarz mi nasunął ten pomysł ! Dziekuje ślicznie za pomoc !

2

Radzę w ten sposób deklarować wskaźniki na funkcji:

typedef HWND CreateButtonFunction( HINSTANCE, HWND, char*, COLORREF, int, int, int, int, int, DWORD, HRGN, void*);
CreateButtonFunction *CreateButton;

przed tym błędem zostałbyś uchroniony w postaci jaśniejszego komunikatu.

1

Źle robisz, że tworzysz dwa pliki nagłówkowe.
Po to się robi to #ifdef BUILD_DLL, by ten sam nagłówek był użyty podczas kompilacji programu co podczas kompilacji DLL-ki.

0

@Azarien i wtedy muszę nieco zmodyfikować funkcję

HINSTANCE InitializeButton(HINSTANCE hInstance, LPCSTR sciezka);

?

W programie najpierw załadować dllkę i potem wczytać funkcję Initialize() umieszczoną w pliku nagłówkowym DLL-ki?
Wtedy funkcja ta wyglądałaby tak?

 HINSTANCE InitializeButton(HINSTANCE hInstance, HINSTANCE hDll){
    f_RejestrujButton = (RejestrujButtonFunction)GetProcAddress( hDll, "f_RejestrujButton" );
    if(!f_RejestrujButton)
     MessageBox(0, "f_RejestrujButton", "Blad pobierania procesu", MB_OK);
    f_CreateButton = (CreateButtonFunction)GetProcAddress( hDll, "f_CreateButton" );
    if(!f_CreateButton)
     MessageBox(0, "f_CreateButton", "Blad pobierania procesu", MB_OK);

    (f_RejestrujButton)(hInstance);
    return hDll;
}

Ale ale... Jeżeli korzystam z pliku nagłówkowego, to chyba nie muszę już dynamicznie wczytywać funkcji? Gubię sie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1