I created a DLL file (helloWorld.dll):
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define DLL_FUNC extern "C" __declspec(dllexport)
DLL_FUNC int __stdcall Hello() {
MessageBox(HWND_DESKTOP, "Hello, world", "MEssage", MB_OK);
return 0;
}
After that I created a cpp where I would like to call (useDLL.cpp)
#include <windows.h>
#include <stdio.h>
int main () {
typedef void (*pfunc)();
HINSTANCE hdll = LoadLibrary("HelloWorld.dll");
pfunc Hello;
Hello = (pfunc)GetProcAddress(hdll, "hello");
Hello();
return 0;
}
How can I call the Hello() function?
The code in the question contains a number of errors:
LoadLibrary returns HMODULE and not HINSTANCE
The function pointer has the wrong return value and an incorrect calling convention.
Function names are case sensitive and you must account for name decoration.
You did no error checking at all. Your code probably fails on the call to GetProcAddress, returns NULL and then bombs when you try to call the function at NULL.
So you need something like this:
typedef int (__stdcall *HelloProc)();
....
HMODULE hdll = LoadLibrary("HelloWorld.dll");
if (hdll == NULL)
// handle error
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "_Hello#0");
if (Hello == NULL)
// handle error
int retval = Hello();
The function name is decorated because you used __stdcall. If you had used __cdecl, or a .def file, then there would have been no decoration. I'm assuming MSVC decoration. It seems that decoration differs with your compiler, mingw, and the function is named "Hello#0".
Frankly it's much easier to do it with a .lib file instead of calling LoadLibrary and GetProcAddress. If you can, I'd switch to that way now.
You need to specifically search and find specific functions you are lookins for, check out this link:
Calling functions in a DLL from C++
Related
I am trying to call cygwin compiled dll in wisual studio environment.
If I compile dll which have function without any library (just return any number),
it works ok, but if I call for example stdio.h, and function with writing file, or just printf function, does not work ( in case of printf function has exited with code 1536).
#include <stdio.h>
int myfunc()
{
char* strtxt = "test";
FILE *hF = fopen( "Newlogtst.txt", "w" );
if(hF == 0)
{
return 5;
}
fputs( (const char*)strtxt, hF );
fclose(hF);
return 1;
}
int tst()
{
return 25;
}
function tst works ok, function myfunc make empty file Newlogtst.txt and shows exception .
`
Exception thrown at 0x6113333A (cygwin1.dll) in CygwinDlltest.exe:
0xC0000005: Access violation reading location 0x004E0059.
If there is a handler for this exception, the program may be safely
continued.
`
in visual studio I am using this code
#include <windows.h>
typedef int (*PFN_HELLO)();
typedef void (*PFN_CYGWIN_DLL_INIT)();
int main()
{
PFN_HELLO func;
HMODULE hLib, h = LoadLibrary(TEXT("C:\\cygwin\\bin\\cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT) GetProcAddress(h,"cygwin_dll_init");
init();
hLib = LoadLibrary (TEXT("C:\\Cygwin\\home\\azatyan\\TestDynamicLink\\mydll.dll"));
func = (PFN_HELLO) GetProcAddress (hLib, "myfunc");
return func();
}
please help what should I do to use library functions.
You don't check the returncode of GetProcAddress().
If you compile it in C++, the names are mangled differently, (which is why GetprocAddress() will return NULL btw.) because they are different compilers.
If you are just using basic functions like in your example, you should declare them as extern "C" so that they wont get mangled. Also make sure that the __declspec export statement are used correctly when compiling the DLL.
This is my exported function in dll1
extern"C" __declspec(dllexport) int FUN1(char* p){
return p[0];
}
I am calling this FUN1 from other project.Below is the code
#include
#include
using namespace std;
typedef int (*MYFUN1)(char*);
int main()
{
HMODULE hMod = LoadLibrary ("C:\\Users\\admin\\Documents\\Visual Studio 2010\\Projects\\CalledFun\\Debug\\CalledFun.exe");
if(hMod != NULL)
{
MYFUN1 pCtor = (MYFUN1) GetProcAddress (hMod, "FUN1");
int a = pCtor("calling a value") ;
cout<<a;
}
}
If I remove the extern "C" from dll1 then that function address is returning as NULL when calling GetProcAddress in dll2. Since both are written in c++ I thought name mangling will not effect this.I thought if we use c and c++ libraries combinely then only we need to mention extern "C" ,Can anyone help me to get out of this confusion
Thanks in advance
You need to disable name mangling because you are using Windows API like LoadLibrary to which you provide function name. Windows API an LoadLibrary in particular know nothing about your compiler name mangling, so you need to turn it off.
I do not understand DLLs very well, so I've constructed a simple example that I woudl like some help with. I have a simple dll here.
// HelloDLL.cpp
#include "stdafx.h"
int __declspec(dllexport) Hello(int x, int y);
int Hello(int x, int y)
{
return (x + y);
}
How would I call the Hello(int x, int y) function in a separate program once I've run LoadLibrary()? Here's a rough layout of what I have so far but I'm not sure if what I have is correct, and if it is, how to proceed.
// UsingHelloDLL.cpp
#include "stdafx.h"
#include <windows.h>
int main(void)
{
HINSTANCE hinstLib;
// Get the dll
hinstLib = LoadLibrary(TEXT("HelloDLL.dll"));
// If we got the dll, then get the function
if (hinstLib != NULL)
{
//
// code to handle function call goes here.
//
// Free the dll when we're done
FreeLibrary(hinstLib);
}
// else print a message saying we weren't able to get the dll
printf("Could not load HelloDLL.dll\n");
return 0;
}
Could anyone help me out on how to handle the function call? Any special cases I should be aware of for future usage of dlls?
After loading the library, what you need is to find the function pointer. The function Microsoft provides is GetProcAdderess. Unfortuantely, you have to know function prototype. If you don't knwo, we are going all the way to COM/DCOM, etc. Probably out of your scope.
FARPROC WINAPI GetProcAddress( _In_ HMODULE hModule, _In_ LPCSTR lpProcName );
So in your example, what you do nromally is like this:
typedef int (*THelloFunc)(int,int); //This define the function prototype
if (hinstLib != NULL)
{
//
// code to handle function call goes here.
//
THelloFunc f = (THelloFunc)GetProcAddress(hinstLib ,"Hello");
if (f != NULL )
f(1, 2);
// Free the dll when we're done
FreeLibrary(hinstLib);
}
I use eclipse and mingw compilier (c++).
I would like to create a dll file which contains a lot of strings.
After that I would like to call with LoadString() to read the string (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647486(v=vs.85).aspx)
my dll file:
#define WIN32_LEAN_AND_MEAN
#define DLL_FUNC extern "C" __declspec(dllexport)
DLL_FUNC int __stdcall Hello() {
return 0;
}
my cpp file:
#include <windows.h>
#include <stdio.h>
int main () {
typedef int (__stdcall *HelloProc)();
HMODULE hdll = LoadLibrary("HelloWorld.dll");
if( hdll == NULL){
MessageBox(HWND_DESKTOP, "Wrong dll path", "Message", MB_OK);
}
else {
typedef int (__stdcall *HelloProc)();
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "Hello#0");
if(Hello == NULL){
//LoadString();
MessageBox(HWND_DESKTOP, "Hello is NULL", "Message", MB_OK);
}
else{
Hello();
}
}
return 0;
}
How do I create the strings? And how to call with LoadString()?
I think you want to read about resources so that you can build a resource-only DLL containing a string table. Try searching the MSDN site you referenced for things like resource compiler and maybe how to build a resource only DLL and how to use string tables. I'm sure you will find documentation and examples at Microsoft and, if not, with Google.
Oh, your DLL is not required to be resource only, I got that from your comment "I would like to create a dll file which contains a lot of strings." It is actually even easier (maybe more straightforward) to do if your DLL will also contain code. Then you'd want to search for adding resources to a DLL and things like that.
Hello guys: I've loaded my DLL in my project but whenever I use the GetProcAddress function. it returns NULL! what should I do?
I use this function ( double GetNumber(double x) ) in "MYDLL.dll"
Here is a code which I used:
typedef double (*LPGETNUMBER)(double Nbr);
HINSTANCE hDLL = NULL;
LPGETNUMBER lpGetNumber;
hDLL = LoadLibrary(L"MYDLL.DLL");
lpGetNumber = (LPGETNUMBER)GetProcAddress((HMODULE)hDLL, "GetNumber");
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:
There is no exported function named GetNumber
There is an exported function named GetNumber, but it is not marked extern "c", resulting in name mangling.
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();
};
You might want to check if your GetNumber function is exported as an __stdcall function.
If so, try GetProcAddress(hDLL, "_GetNumber#N");, where N is the total number of bytes of GetNumber's argument list. For example, if your function signature is int GetNumber(int a, double b), its real name in DLL will be _GetNumber#12.
Reference: __stdcall
Most probably LoadLibrary() failed. You just can't see that because apparently you are not checking what it is returning:
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
EDIT:
We don't know how you are exporting the function on the DLL code, but this thread explains a couple of reasons on why GetProcAddress fails.