Using DLL's

Hello:

I wrote a test DLL.
well... I'd like to test if it works in an exe project... But I don't know how to use it...

The Dll is called Test.DLL (I also have a Test.Lib file) Well theese files are in "C:\Test\Release\" directory.
The DLL has an:

EXPORT void CALLBACK Message (void) funtion

What do I have to do to use the "Message" function in my exe project?.

Thanks.

LVL 1
MarscAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MarscAuthor Commented:
By the way...

Visual C++ is the compiler
0
MarscAuthor Commented:
Edited text of question.
0
inprasCommented:
Hi Marsc
instead of EXPORT use
function prototype in dll
__declspec( dllexport ) void func();

in the exe use
__declspec( dllimport ) void func();

in any function
call func();

copy ur dll file to system directory and set the linkpath to the library
this is called static linking U can also use LoadLibrary and GetProcAddress and FreeLibrary
Hope this helps
Regrds
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

MarscAuthor Commented:
I'm sorry

What I want to do is not working with both projects open (I mean... I don't want to have The Dll project and The exe project in the same WorkSpace).

Actually... The Dll was built succefully... now, what I want to use it from an exe project...
Mi doubt is that... how to use a Dll from an exe... For instances... For calling api functions, I should have to include the right header file, and then add the .LIB... But the real question is, how to use a DLL... How to declare the function, etc...

Thanks any way
0
viktornetCommented:
you should use LoadLibrary() with the name of the library and assign the return value to a variable... then you should use that variable with GetProcAddress() to get the address of the proc and save that too since you'll need it to call the function.... then you just need to call the function by using the address returned by GetProcAddress()... when you're done you just call FreeLibrary() and the variable (handle) that you used earlier to free the memory taken up by the DLL.... that's about it..

if you need more help lemme know!!

..-=ViKtOr=-..
0
MarscAuthor Commented:
There is something that I don't understand...

When I call a windows api, I don't need to use LoadLibrary, And they are in DLL's
(Actually I don't know if it is used by a header file)...

Well... I will test what you say... If it works, I will accept the answer.

Thnaks.
0
MarscAuthor Commented:
And well...

I was reading the documentation... It seems that the api calls are defined by macros... Well... That is what I understood...

But only one question...

Once I called GetProcAddress (...) I have an address to a procedure...
How do I call it?...

For instances.
I have a dll with a bool Function (int)
How can I call this function?.

Thanks
0
viktornetCommented:
Marsc, the kernel32.dll/user32.dll and other required DLLs that the system needs in order to run are being loaded as the windows is starting... that's why you don't need to load them on your own...

What you're probably talking about is what inpras was trying to explain... you have to export the functions that you'd like to access outside the DLL and import them in your own EXE. inpras, shows you some pseudo code on how to do that. If you need more help, please let me know!

..-=ViKtOr=-..
0
viktornetCommented:
what you do is define a pointer to a function just like the one you have in the DLL... e.g.

bool (*MyFunc)(int);

then you can do this...

.....
MyFunc = GetProcAddress(hLib, "MyFunc");
if (MyFunc != NULL)
  MyFunc(20);
.....

Hope this helps!

..-=ViKtOr=-..
0
inprasCommented:
Hi

U have misunderstood the concept of my answer the steps defined are how to create a dll once U build the dll in different work space then in the workspace of exe u r buliding
//this is function exported in dll
__declspec( dllimport ) void func();

now calling of that function
call ---- func();

before this

copy ur dll file to system directory and set the linkpath in project settings of exe workspace to the library of ur dll this is called static linking

U can also use LoadLibrary and GetProcAddress and FreeLibrary
Hope this helps
0
MarscAuthor Commented:
Well...

I don't find a solution...
My DLL looks like this.
---------------------------------
A header file

#define EXPORT __declspec (dllexport)
EXPORT int CALLBACK Poner (void);

---------------------------------
A Source file

#Include "The header file" //(Of course it is not named like this :-).

BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,           LPVOID lpReserved)
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
 MessageBox (NULL,"Process attach","",NULL);
return true;
//And a case process Detach that returns something
Default: return true;

}
}

EXPORT int CALLBACK Message (void)

{
MessageBox (NULL,"It works","Msg",NULL);
return 150;
}
All is built succefully.

----------------------------------------

In the exe I tried all (Well... I guess there are remaining things to try :)
When the library is loaded in the exe...
The DllMain Function is called (The message box "Process Attach" is shown)

Well...
I'd like to know, What exactly do I have to do, to use the DLL working?.

I know there are to ways to link libraries, Implicity and Explicity.
I'm interested in both.

I tried also in the EXE:

__declspec( dllimport ) int Message(void);

I Copied the .LIB file to the Lib directory of Vc++ (Where all the .LIB's
are) I added this to the field "Object/Library Modules" in project setting...

And What I get is "Unresolved external".

Well... At this point I should tell:
I started giving few points for this question because I thought it was an easy question... As far as I can see now... It might be hard.
I'm willing to increase the points.

Well... I'd like to know how to link my Exe project to a DLL in both ways...
Implicity and explicity
When I say Explicity, I mean, using loadlibrary explicity :)

If possible: Some lines of code that get the DLL described above working,
in two ways...

I thank you all for the patience you are having...
My emaial address is in my profile if you have some sample of code you could send me.

Thank to you all very much.

0
MarscAuthor Commented:
I mistyped the prototype In my reference of the DLL project header file... In the reality it has the same name of the Function Definition.
thanks
0
viktornetCommented:
Ok, here is some source code I just put together for  you... Hope this helps...

========= Test.cpp (DLL) ==========
#include <windows.h>

bool APIENTRY DllMain(HANDLE hModule, DWORD reason_for_call, LPVOID lpReserved)
{
  return true;
}

__declspec (dllexport) int Message(void)
{
  MessageBox (NULL,"It works","Msg",NULL);
  return 150;
}

======= TestApp.cpp (Test Application) ========
#define WIN32_MEAN_LEAN

////////////////////////
////// INCLUDES ////////
////////////////////////

#include <windows.h>
#include <windowsx.h>

///////////////////////
////// DEFINES ////////
///////////////////////

#define TITLE "DLL TEST"
#define WIDTH 320
#define HEIGHT 200

///////////////////////
////// GLOBALS ////////
///////////////////////

MSG msg;
HWND hMainWnd;
HWND hBtn1;
HWND hBtn2;
WNDCLASS wc;

//////////////////////////
////// PROTOTYPES ////////
//////////////////////////

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

// Importing of function for implicit call

__declspec (dllimport) Message(void);

//////////////////////////////
////// IMPLEMENTATION ////////
//////////////////////////////


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
  wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
  wc.lpfnWndProc = WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInst;
  wc.hIcon = LoadIcon(0, IDI_APPLICATION);
  wc.hCursor = LoadCursor(0, IDC_ARROW);
  wc.hbrBackground = GetStockObject(WHITE_BRUSH+1);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "WC1";

  RegisterClass(&wc);

  hMainWnd = CreateWindow("WC1", TITLE, WS_OVERLAPPEDWINDOW, 0, 0, WIDTH, HEIGHT, 0, 0, hInst, NULL);
  hBtn1  = CreateWindow("BUTTON", "Using export/import", WS_CHILD | WS_VISIBLE, 10, 50, 300, 20, hMainWnd, 0, hInst, NULL);
  hBtn2  = CreateWindow("BUTTON", "Using LoadLibrary/FreeLibrary", WS_CHILD | WS_VISIBLE, 10, 80, 300, 20, hMainWnd, 0, hInst, NULL);

  ShowWindow(hMainWnd, SW_SHOW);
  UpdateWindow(hMainWnd);

  while(GetMessage(&msg, 0, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return (msg.lParam);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  HDC hDC;
  PAINTSTRUCT ps;

  switch (uMsg) {
    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    case WM_PAINT:
      hDC = BeginPaint(hMainWnd, &ps);                  
      EndPaint(hMainWnd, &ps);
      break;

    case WM_COMMAND:
      // If button one is pressed do this
      if ((HWND) lParam == hBtn1)
        Message();
      // otherwise do the following
      else if ((HWND) lParam == hBtn2) {
        // I'm declaring all the variables and function pointers
        // here so you know how they are being used

        HINSTANCE hLib;
        FARPROC MessageFunc;

        // Load the library
        hLib = LoadLibrary("test.dll");
        // If it was loaded correctly continue
        if (hLib) {
          // Get the address of the function...
         // Note: I didn't use GetProcAddress(hLib, "Message") because
         // GetProcAddress() makes the string you pass uppercase
         // and since the function is not all uppercase as in "MESSAGE"
         // it won't be recognized!!
         // That's why I'm using MAKEINTRESOURCE() to pass an ordinary
         // value

          MessageFunc = GetProcAddress(hLib, MAKEINTRESOURCE(1));

          // If we got the address of the function, execute it...
          if (MessageFunc)
            MessageFunc();
          // Finally free the library...
          FreeLibrary(hLib);
        }
      }
      break;
  }
  return (DefWindowProc(hWnd, uMsg, wParam, lParam));
}
==============================
Compile the DLL separately, and then copy test.dll and test.lib to your other app's working space (where the source codes are)... then you need to add test.lib to your project (the app)... Rebuild all and there shouldn't be any problems. I used VC++ 5 to compile it and it worked just fine!

If you need more help, let me know!

..-=ViKtOr=-..
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MarscAuthor Commented:
Well.

I didn't do exactly what you said... but your code helped me to make some modifications in my code... And got it working...
For instances... for Implicity link...
I declared the DLL function exactly in the same way that I did in the DLL Header file... It worked.

Abou explicity it worked...
I have a simple question...
Well... I added a seccond function to the DLL, And to get the address of this seccond function I got the address with a "DrawRect = GetProcAddress(hLib, MAKEINTRESOURCE(2))"... It worked...
Am I right if I say that the paramenter you pass to the MAKEINTRESOURSE is the order in wich the function is in the DLL?.

Until now we were talking about functions that don't receive any parameter. DrawRect function has something like this:

GetDC (NULL); //
Rectangle (...); //Draws a rectangle directly to the screen.
ReleaseDC (...);

But I'd like it to receive a HWND... I tried it but in the exe when I do
The simple question is.
How can I receive a pointer to a function that receives a parameter in this case would be a HWND.
I guess it can be solved by modifing some line of code...

Well...
Your comment is going to be accepted as an answer right now (I will reject your answer and then accept your comment)

I don't have words to tell you how much I thank you for your patience.

Thanks.

0
MarscAuthor Commented:
As I told you... I'm accepting your comment as an answer.

Thanks
0
viktornetCommented:
>>I didn't do exactly what you said
I never said you have to #;o)
The code I posted was just as a guidance for you (hopefully) ;)

>>Am I right if I say that the paramenter you pass to the
>>MAKEINTRESOURSE is the order in wich the function is in the DLL?.
YES!!

>>How can I receive a pointer to a function that receives a parameter
>>in this case would be a HWND.
>>I guess it can be solved by modifing some line of code...

For implicit call you'd have to do the following..

in the DLL:

__declspec (dllexport) int Message(char* msg);

and in the proggy you'd have to do..

__declspec (dllimport) int Message(char* msg);

..... for an explicit call the following should work just fine..

FARPROC Func;
HINSTANCE hLib;

hLib = LoadLibrary("whatever.dll");
Func = GetProcAddress(hLib, MAKEINTRESOURCE(1));
Func("Whatever");
FreeLibrary(hLib);

No error checking, though...

That's about it! If you have any other questions let me know!!

..-=ViKtOr=-..
0
MarscAuthor Commented:
Well...

something like that generates this error:

too many actual parameters
Error executing cl.exe.

Well I appetiate all the help that you gave me...

But at this point, I think I better post another question with this new DLL problem... (It was more easy to write it than to use it).

Well...
Thanks to you... And I'd like to mention that I Appretiate Inpras's Help too.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.