?
Solved

DLL Loading and calling methods

Posted on 2003-03-13
11
Medium Priority
?
493 Views
Last Modified: 2013-12-03
Hi,
    I created a win32 dll usin VC++ 6 . I complied it without any warning. I created a MFC application that calls methods declared in that dll. I used LoadLibrary() for loading the library and it was successful.But reteaving the funtion pointer using GetProcAddress() failed. Can anybody throw some light on what could have gone wrong ?
    This is urgent since I am stuck and want a reply soon.
0
Comment
Question by:makri
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +3
11 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 8127634
One possible reason is wrong declaration of exported Dll functions. To see how this should be done create Win32 Dll using Application Wizard and select "Dll that exports some symbols". Read the code generated by Wizard.

Other reason may be incorrect using of GetProcAddress. Show your code (including functions and function pointers declarations, calling LoadLibrary and GetProcAddress).
0
 
LVL 86

Expert Comment

by:jkr
ID: 8127676
>>Can anybody throw some light on what could have gone wrong ?

Try

dumpbin.exe /exports mydll.dll

to see what functions you are actually exporting and examine the names. If you are using source files with a .cpp extension, the compiler/linker will decorate the export names.
0
 
LVL 1

Expert Comment

by:nivd
ID: 8131558
To verify that you call the right function compile your DLL using a map file (on the link setting mark generate map file).
Using this file you'll be able to understand the exact name of the function that you should use when you call GetProcAddress.

Are you trying to load C++ functions or C functions.
Did you use extern C blocks?
0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
LVL 3

Accepted Solution

by:
JackThornton earned 420 total points
ID: 8134129
Names are almost invariably decorated, whether C or C++.
So, if you write a function called "DoThis" you cannot ask for the procaddress for "DoThis" - you must ask for the name as it was mangled by the compiler.

The 'C' naming convention for DLL exported function is the most straightforward:

 underbar procname @ bytes_of_params

So, if you have a 'C' function called "DoThis" that takes an int, the actual name as exported by the DLL would be:

_DoThis@4

A "dothat" function that takes a double and a pointer, for 12 bytes of parameters, would be called "_dothat@12". And so forth.

The best thing to do to make sure you have predictable names is to declare your exported functions as 'C' functions - you can do this in C++ and all will be well with the world - like "nivd" asked about extern C blocks. So, declare your function like this in the header file:

extern 'C' {
   void dothat(float paramA, int *paramB);
};

Then the name that is exported will follow the convention I described above. So, after you do your LoadLibrary, you can call:

GetProcAddress(hDLL, "_dothat@12");

and get a pointer to the above-described function.

To see what names you're currently getting, take jkr's advice and run dumpbin over your DLL.
0
 

Author Comment

by:makri
ID: 8134579
I have tried dumpbin. It is not working , it is giving message "A required .DLL file,MSPDB60.dll was not found."
So i guess there is a problem with installation.

I am sending a non working sample code modified my Jacks suggetion :-
(Only relevent parts )
The DLL file <<dsncreate.h>>:

#ifdef DSNCREATE_EXPORTS
#define DSNCREATE_API __declspec(dllexport)
#else
#define DSNCREATE_API __declspec(dllimport)
#endif

// This class is exported from the dsncreate.dll
extern DSNCREATE_API int nDsncreate;

extern "C" {
DSNCREATE_API int fnDsncreate(int a);
};



The implementation <<dsncreate.cpp>>
// These are generated by the VC++ wizard.

DSNCREATE_API int nDsncreate=10;

// This is an example of an exported function.
DSNCREATE_API int fnDsncreate(int a)
{
     return 42;
}

The <<Test.h>> file , MFC Dialog based application Has "TestDlg" dialog in it. In its OnOK() i am doing this :


void CTestDlg::OnOK(){

     typedef  int (CALLBACK* LPFNDLLFUNC)(void);

     HINSTANCE hDLL;              
     LPFNDLLFUNC lpfnDllFunction;    

     hDLL = LoadLibrary("dsncreate");
     if (hDLL != NULL)          
     {
         
       
     lpfnDllFunction = (LPFNDLLFUNC)GetProcAddress   (hDLL,"_fnDsncreate@4");
     if (!lpfnDllFunction)
     {
          // handle the error
          MessageBox("Failure loading external declared function");
                   
          FreeLibrary(hDLL);
             return ;
     }
     else
     {
          // call the function
          if(  lpfnDllFunction() ) {
                    MessageBox("Success");
          }
          else MessageBox("Failure");
               FreeLibrary(hDLL);
         
     }
     }else {
          MessageBox("Failure Loading DLL");
     }
     
}


Also , one more question the dsncreate.h declares an extern int nDsncreate. How do I access this from my application ? If I use Explicit linking (?) as I have done here, how do I access it ?
0
 

Author Comment

by:makri
ID: 8134604
oops ! sorry , I send the wrong version of Test application . The method signature actually is

     typedef  int (CALLBACK* LPFNDLLFUNC)(int  );

and it is called as :

     // call the function
     if(  lpfnDllFunction(2) ) {
         MessageBox("Success");
     }
     else MessageBox("Failure");
     FreeLibrary(hDLL);

I am bogged , I admit.
0
 

Author Comment

by:makri
ID: 8135088
Yes at last almost everything working now . The required .DLL file for the dunmpbin was simply misplaced in vb98 folder. The result showed name as
fnDsncreate as having name ?fnDsncreate@@YAHXZ
and nDsncreate as ?nDsncreate@@3HA .
When I gave this name it worked .
0
 
LVL 86

Expert Comment

by:jkr
ID: 8138338
>>When I gave this name it worked .

Declare the function as 'extern "C"' to turn off the name mangling.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8139800
Create a .DEF file.  That eliminates the naming problems.

=-=--=-==--=-==-=-=-=-=-=-=- start of file <projname>.DEF

; MyDll.def -- add this to the source file list in the IDE

LIBRARY      "MYDLL"
DESCRIPTION  'Does cools stuff'

EXPORTS
MyExportedProc  @1

=-=--=-==--=-==-=-=-=-=-=-=- end if file

-- Dan
0
 
LVL 86

Expert Comment

by:jkr
ID: 8144069
>>Create a .DEF file

Also an option. I consider 'extern "C"' easier :o)
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8144350
I agree.  The trick is to do:

    extern "C" {
          DSNCREATE_API int MyFn(int param1, char* pszParm2);
    }

in the .h file.  Then you can define the fn normally in the cpp file:

    int MyFn(int param1, char* pszParm2);

Note that even the
     DSNCREATE_API
is not needed.

-- Dan
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question