Getprocaddress Function in C++

GetProcAddress function in C++

Checking return codes and calling GetLastError() will set you free. You should be checking return codes twice here. You are actually checking return codes zero times.

hDLL = LoadLibrary(L"MYDLL.DLL");

Check hDLL. Is it NULL? If so, call GetLastError() to find out why. It may be as simple as "File Not Found".

lpGetNumber = (LPGETNUMBER)GetProcAddress((HMODULE)hDLL, "GetNumber");

If lpGetNumber is NULL, call GetLastError(). It will tell you why the proc address could not be found. There are a few likely scenarios:

  1. There is no exported function named GetNumber
  2. There is an exported function named GetNumber, but it is not marked extern "c", resulting in name mangling.
  3. hDLL isn't a valid library handle.

If it turns out to be #1 above, you need to export the functions by decorating the declaration with __declspec(dllexport) like this:

MyFile.h

__declspec(dllexport) int GetNumber();

If it turns out to be #2 above, you need to do this:

extern "C"
{
__declspec(dllexport) int GetNumber();
};

GetProcAddress function returning NULL

It's because the name is mangled (i.e. the name of the function is not "run" but something different).

Your code will work with (for MSVC 2013 where I tested):

add = (Addition)GetProcAddress(hDLL, "?run@dllclass@newer@@SAHHH@Z");
cout << add(1, 2) << endl;

In general, if you want to load a class via plugin, your best shot is to use virtual interface. An example:

//dummy2.h
namespace newer
{
class dllclass_interface
{
public:
virtual int run(int a,int b) = 0;
};

}

extern "C" __declspec(dllexport) newer::dllclass_interface* getDllClass();

//dummy2.cpp
#include <iostream>
using namespace std;

#include "dummy2.h"

namespace newer
{
class dllclass: public dllclass_interface
{
public:
virtual int run(int a,int b);
};

int dllclass::run(int a,int b)
{
return a+b;
}
}

extern "C" newer::dllclass_interface* getDllClass()
{
static newer::dllclass instance;
return &instance;
}

typedef newer::dllclass_interface* (*GetClassFunc)();

GetClassFunc getClassFunc = (GetClassFunc)GetProcAddress(hDLL, "getDllClass");

newer::dllclass_interface* dllClass = getClassFunc();
cout << dllClass->run(a, b) << endl;

LoadLibrary and GetProcAddress in a function C/C++

Try something like this:

#include <map>
#include <string>

std::map<std::wstring, HINSTANCE> libs;

template<typename T>
bool dynamyc_function(LPCWSTR libname, LPCSTR funcname, T *func)
{
HINSTANCE hlib = libs[libname];
if (!hlib)
{
hlib = LoadLibraryW(libname);
if (!hlib)
{
wprintf(L"could not load the dynamic library %s! %d", libname, GetLastError());
return false;
}
libs[libname] = hlib;
}

*func = (T) GetProcAddress(hlib, funcname);
if (!*func)
{
printf("could not locate the function %s! %d", name, GetLastError());
return false;
}

return true;
}

int main(int argc, char *argv[])
{
typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD);

// resolve function address here
f_funci SetWindowsHookEx2;
if (!dynamyc_function(L"User32.dll", "SetWindowsHookExW", &SetWindowsHookEx2))
return EXIT_FAILURE;

HHOOK hMouseHook = SetWindowsHookEx2(WH_MOUSE_LL, my_function, hInstance, NULL);
if (!hMouseHook)
{
printf("could not set hook! %d", GetLastError());
return EXIT_FAILURE;
}
...
UnhookWindowsHookEx(hMouseHook);

return 0;
}

Alternatively, if you are only interested in a specific function, you can try something like this instead:

typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD);

HHOOK __stdcall Impl_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
HHOOK __stdcall Stub_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
f_funci lpSetWindowsHookExW = &Stub_SetWindowsHookExW;

HHOOK __stdcall Impl_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
}

HINSTANCE hUser32 = NULL;
HHOOK __stdcall Stub_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
{
if (!hUser32)
{
hUser32 = LoadLibraryW("User32.dll");
if (!hUser32)
{
DWORD err = GetLastError();
printf("could not load the dynamic library! %d", err);
SetLastError(err);
return NULL;
}
}

f_funci func = (f_funci) GetProcAddress(hUser32, "SetWindowsHookExW");
if (!func)
{
DWORD err = GetLastError();
printf("could not locate the function! %d", err);
SetLastError(err);
func = &Impl_SetWindowsHookExW;
}

lpSetWindowsHookExW = func;
return func(idHook, lpfn, hMod, dwThreadId);
}

int main(int argc, char *argv[])
{
HHOOK hMouseHook = lpSetWindowsHookExW(WH_MOUSE_LL, my_function, hInstance, NULL);
if (!hMouseHook)
{
printf("could not set hook! %d", GetLastError());
return EXIT_FAILURE;
}
...
UnhookWindowsHookEx(hMouseHook);

return 0;
}

c++ WINAPI call exported function via GetProcAddress

You should be consistent. If you retrieve pointer as a pointer to stdcall function - it must be declared as stdcall in implementation:

//header.h
extern "C" __declspec(dllexport) void __stdcall init(DWORD size);

GetProcAddress for importing a decorated C++ function into C++

I would not start a hunt for the mangled name. It's compiler dependent (which means also version dependent) and even if it works it would be a fragile solution.

I would suggest to get the address of your RegisterFactoriesType in antother way.

Assuming you have, in your plugin, a C-Style init function (whose address is available via GetProcAddress) I would do this:

struct init_data_t
{
RegisterFactoriesType factory ;
... other members
} ;

then inside init (so inside the DLL)

void init(init_data_t *data)
{
init_data->factory = &dll_factory ;
}

Basically you ask the DLL to give you the address of the factory function. The dll code does not need GetProcAddr, it can use address of (&)

Function pointer extracted through GetProcAddress crashes the application

Your function exported from your DLL will be compiled with the C calling convention (__cdecl), but your typedef of the function pointer indicates that you expect to treat it as the Windows calling convention (CALLBACK is a macro for __stdcall). Mixing these two up imbalances the stack.

Either remove CALLBACK from the function pointer declaration, or declare your exported function with __stdcall.



Related Topics



Leave a reply



Submit