In the code below, I check if test.dll has been loaded, and it always returns false... I can't figure out what I'm doing wrong. Can anyone give me a hand?

P.S.: I've triple checked that the DLL is in the running directory.

#include <iostream>
#include <windows.h>

typedef int (*AddFunc)(int,int);
typedef void (*FunctionFunc)();

int main()
{
   AddFunc _AddFunc;
   FunctionFunc _FunctionFunc;
   HINSTANCE hInstLibrary = LoadLibrary((LPCTSTR)("test.dll"));

   if (hInstLibrary)
   {
      _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
      _FunctionFunc = (FunctionFunc)GetProcAddress(hInstLibrary,
         "Function");

      if (_AddFunc)
      {
         std::cout << "23 = 43 = " << _AddFunc(23, 43) << std::endl;
      }
      if (_FunctionFunc)
      {
         _FunctionFunc();
      }

      FreeLibrary(hInstLibrary);
   }
   else
   {
      std::cout << "DLL Failed To Load!" << std::endl;
   }

   std::cin.get();

   return 0;
}

Recommended Answers

All 15 Replies

Just to see what happens, why don't you try a fully qualified path? With constructs such as you are using, its usually GetProcAddress() that causes trouble - not LoadLibrary().

I've changed LoadLibrary((LPCTSTR)("test.dll")) to LoadLibrary((LPCTSTR)("C:/Users/Nicholas Roge/Desktop/test/test.dll")), however there isn't any luck. Unless I misunderstood what you were telling me to try, however.

When LoadLibrary() fails, call GetLastError() to get the error number, then FormatMessage() to format the error message string.

DWORD dwError = GetLastError();
char buf[255];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, dwError,0,
    buf, sizeof(buf));
cout << buf << '\n';

What does GetLastError() say?

I had to look at what was actualy in the buffer to get it to work, but it says that "The specified module could not be found."... But I KNOW for a fact that it has been in all of the locations I've tried.

Sorry. I trust GetLastError more.

it has been in all of the locations I've tried

What about the locations LoadLibrary tried? Is the file "test.dll" a library?

i think you should do it in this way.

# include <stdio.h>
# include <windows.h>
//# include <winbase.h>
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);

int main()
{
	PGNSI pGNSI;
	SYSTEM_INFO si;
	ZeroMemory(&si, sizeof(SYSTEM_INFO));
	pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
	if (pGNSI)
	{
		printf("yes pGNSI exists");
		pGNSI(&si);
		printf("\npage size is : %d\n",si.dwPageSize);
	}
	return 0;
}

This code might be helpful for you
This is a good link. try it and please read REMARKS on this link because they are important
http://msdn.microsoft.com/en-us/library/ms683212%28VS.85%29.aspx

What about the locations LoadLibrary tried? Is the file "test.dll" a library?

In this case, yes, all DLLs are considered libraries for the purpose of LoadLibrary(). That function name could probably have been better named as LoadDLL(), but it wasn't.

i think you should do it in this way.

Nice code and link, but the problem isn't with GetProcAddress(), as the op previously stated.

@Nicholas: If you do not specify the DLL's location then it must be either in the current working directory or in one of the directories in your PATH environment variable. If there are more than one copy of the DLL on your computer then I'd suggest you delete all but one of them so that your program doesn't pick up the wrong (possibly out-of-date) version (been there myself, and done that too.)

I've changed LoadLibrary((LPCTSTR)("test.dll")) to LoadLibrary((LPCTSTR)("C:/Users/Nicholas Roge/Desktop/test/test.dll")), however there isn't any luck. Unless I misunderstood what you were telling me to try, however.

Have you UNICODE defined?
If so, then the following cast

LoadLibrary((LPCTSTR)("test.dll"))

causes this behaviour. The end result is that a non-UNICODE string gets passed to LoadLibraryW() and that will not work.

To fix it, change it to

LoadLibrary((LPCTSTR)_T("test.dll"));

You need to also #include <tchar.h>

LoadLibrary((LPCTSTR)_T("test.dll"));

You need to also #include <tchar.h>

You posted the wrong typcast -- should have been LPWSTR, not LPCTSTR. But with _T macro the typecast is not even needed.

Holy crap mitrmkar! That was the problem. Thank you very much. And thank you to everyone else that was helping out as well.

And while I have you're attention, would anyone mind helping learn to thread?

>>would anyone mind helping learn to thread?

What do you want to thread? A sewing needle? :) You should start another thread if you need to know how to use _pthreads to create threads. But first google for _pthread_create() to see what needs to be done.

Can do! But what is this _pthread business? I WAS talking about threading a needle. lol.

You posted the wrong typcast -- should have been LPWSTR,

I think you maybe misunderstood what I was saying and maybe I'm not quite getting what you are saying .. but anyway.
Having UNICODE defined and doing a LPCWSTR typecast results in

LoadLibraryW((const wchar_t *)"test.dll"); // This will NOT work

And that is actually what was the problem here.

The (LPCTSTR) cast, that I posted, is actually extraneous and can be removed. However, if there is to be a cast, it has to be (LPCTSTR), not LPCWSTR (given that LoadLibrary() macro is used instead of the actual functions).

Yes I know char* can not just simply be typecast to wchar_t*. But if the program is compiled for UNICODE the string has to be converted to wchar_t*, which the _T macro will do as you posted. There is no need at all for the typecast.

This will work whether UNICODE or not (No need to specify the W at the end of LoadLibrary() either because that too is just a typedef for either A or W depending on UNICODE setting. LoadLibrary(_T("test.dll"));

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.