Thread: Getting function address from a DLL module

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    385

    Getting function address from a DLL module

    I built a DLL (WinDll.dll) that exports a function called 'SampleFunction'. I placed the DLL in the same folder as that of the executing application, however it gives an error when I try to get the address of the exported function. Following is the code which loads and tries to make use of the exported function.

    Code:
    #include <windows.h>
    #include "WinDll.h"
    
    typedef int (WINAPI *procP)(HINSTANCE, HINSTANCE, LPSTR, int);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	HINSTANCE hinstlib;
    	LPSTR lpBuffer = (LPSTR)malloc(256*2);
    	GetCurrentDirectory(256,lpBuffer);
    	procP procAddress = NULL;
    
    	strcat(lpBuffer,"\\WinDll.dll");
    	hinstlib = LoadLibrary(TEXT(lpBuffer));
    
    	if(hinstlib == NULL){
    		MessageBox(NULL,lpBuffer, "Bull", MB_OK);
                    exit(0);
    	}
    	else{
    		procAddress = (procP)GetProcAddress(hinstlib,"SampleFunction");   // <--- Problem
    		if(procAddress != NULL){
    			PostMessage(NULL, WM_RBUTTONDOWN, MK_RBUTTON, 0); 	
    		}
    		else{
    			MessageBox(NULL,"Invalid procAddress", "Bull", MB_OK);	
    		}
    	}
    	
    	return 0;
    }
    Please help.
    Last edited by juice; 01-23-2014 at 09:18 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Does LoadLibrary fail, or GetProcAddress? What does GetLastError say about it?

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Did you compile your dll as C or C++? If C++, the name might be "mangled".
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by tabstop View Post
    Does LoadLibrary fail, or GetProcAddress? What does GetLastError say about it?
    GetProcAddress fails.

  5. #5
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by oogabooga View Post
    Did you compile your dll as C or C++? If C++, the name might be "mangled".
    I'm compiling everything in Pelles C.

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    I guess we need to see how you're "exporting" the function.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Here a clip from IDA Pro indicating names of the exported functions from WinDll.dll




    Getting function address from a DLL module-capture-png

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Did you read all this: Dynamic-Link Libraries (Windows)


    You could try using the "ordinal value".
    Code:
    GetProcAddress(hinstlib, (char*)1);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  9. #9
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Following is the code for WinDll.h

    Code:
    // INCLUDE FILE generated by "Pelles C for Windows, version 3.00".
    
    #ifndef _WINDLL_H
    #define _WINDLL_H
    
    #ifdef _WINDLL_
    #define WINDLLAPI  __declspec(dllexport)
    #else
    #define WINDLLAPI  __declspec(dllimport)
    #endif /* _WINDLL_ */
    
    #ifndef WINAPI
    #define WINAPI  __stdcall
    #endif
    
    WINDLLAPI int WINAPI SampleFunction(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
    
    #endif /* _WINDLL_H */

  10. #10
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Following is dllmain.c

    Code:
    #define WIN32_LEAN_AND_MEAN  /* speed up */
    #include <windows.h>
    #include <windowsx.h>
    #include <commctrl.h>
    #include <tchar.h>
    
    #define _WINDLL_
    #include "WINDLL.h"
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    LPSTR String;
    
    WINDLLAPI int WINAPI SampleFunction(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
    {
        static char szAppName[] = "winhello";
        HWND        hwnd;
        MSG         msg;
        WNDCLASSEX  wndclass;
    	String = lpCmdLine;
    
        /*  Fill in WNDCLASSEX struct members  */
    
        wndclass.cbSize         = sizeof(wndclass);
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 0;
        wndclass.hInstance      = hInstance;
        wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wndclass.lpszClassName  = szAppName;
        wndclass.lpszMenuName   = NULL;
    
        
        /*  Register a new window class with Windows  */
    
        RegisterClassEx(&wndclass);
    
    
        /*  Create a window based on our new class  */
    
        hwnd = CreateWindow(szAppName, "Hello, world!",
    			WS_OVERLAPPEDWINDOW,
    			CW_USEDEFAULT, CW_USEDEFAULT,
    			CW_USEDEFAULT, CW_USEDEFAULT,
    			NULL, NULL, hInstance, NULL);
    
    
        /*  Show and update our window  */
    
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
    
        /*  Retrieve and process messages until we get WM_QUIT  */
    
        while ( GetMessage(&msg, NULL, 0, 0) ) {
    	TranslateMessage(&msg);    /*  for certain keyboard messages  */
    	DispatchMessage(&msg);     /*  send message to WndProc        */
        } 
    
    
        /*  Exit with status specified in WM_QUIT message  */
    
        return msg.wParam;
    }
    
    
    /*  Window procedure  */
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
        PAINTSTRUCT ps;
        HDC         hdc;
    
        
        /*  Switch according to what type of message we have received  */
    
        switch ( iMsg ) {
        case WM_PAINT:
    
    	/*  We receive WM_PAINT every time window is updated  */
    
    	hdc = BeginPaint(hwnd, &ps);
    	TextOut(hdc, 100, 100, String, 13);
    	EndPaint(hwnd, &ps);
    	return 0;
    
        case WM_DESTROY:
    
    	/*  Window has been destroyed, so exit cleanly  */
    
    	PostQuitMessage(0);
    	return 0;
        }
    
    
        /*  Send any messages we don't handle to default window procedure  */
        
        return DefWindowProc(hwnd, iMsg, wParam, lParam);
    }

  11. #11
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by oogabooga View Post
    Did you read all this: Dynamic-Link Libraries (Windows)
    Yes oogabooga, that is my source of reference.

  12. #12
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by oogabooga View Post
    You could try using the "ordinal value".
    Code:
    GetProcAddress(hinstlib, (char*)1);
    Hey! That works!!

    How??
    And why not the other way??

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by juice View Post
    Hey! That works!!

    How??
    And why not the other way??
    Revert to the older code and call GetLastError() after the point of failure

  14. #14
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by whiteflags View Post
    Revert to the older code and call GetLastError() after the point of failure
    127
    Code:
    ERROR_PROC_NOT_FOUND
    
        127 (0x7F)
    
        The specified procedure could not be found.
    From msdn

  15. #15
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by juice View Post
    Hey! That works!! How?? And why not the other way??
    The concept of ordinals is described here:
    GetProcAddress function (Windows)


    I don't know why it's not working the other way.
    Could it be some sort of unicode problem?
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to specify address for a function
    By pilgrim in forum Linux Programming
    Replies: 9
    Last Post: 09-28-2010, 12:20 PM
  2. Function call from another .c module
    By Ali.B in forum C Programming
    Replies: 14
    Last Post: 08-03-2009, 11:45 AM
  3. Getting function names from a module
    By Thantos in forum Windows Programming
    Replies: 2
    Last Post: 01-19-2005, 09:52 AM
  4. Isolating a C++ function/module with C
    By freedomnet in forum C Programming
    Replies: 2
    Last Post: 05-11-2004, 02:16 PM
  5. module base address
    By cppdude in forum Windows Programming
    Replies: 2
    Last Post: 03-29-2002, 06:14 PM