Solved

.exe HINSTANCE problem

Posted on 1997-10-16
9
1,039 Views
Last Modified: 2011-09-20
I am using VC++ 4.0 on 95.
Here's a description of the problem. There is a function in my .exe that I need to access in one of my .dlls. I want to export the Instance Handle of the .exe to a .dll in order to access the function from the .exe in the .dll.
I have set up an exported function in my .dll and use this and the AfxGetInstanceHandle function in the .exe to pass the HINSTANCE of the .exe to the .dll. BUT it consistently passes a value of 0x00400000 to the .dll. When I attempt to use this HINSTANCE value in the .dll with the GetProcAddress function nothing happens. I used GetLastError() and got an error code of 126 which is "The specified module cannot be found".
Sorry about the long-winded description but this is all new territory to me and it has me stumped.
Cheers - Rodger.  
0
Comment
Question by:rfaherty
[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
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1171569
Personally, I think you would be better of passing the handle to the DLL procedure as a parameter.

But if you want to do it this way, your technique should work.  

But there is an easier way.  If your DLL only needs the instance handle of the Exe, just use the API procedure GetModuleHandle.  If you specify a NULL pointer for the name, it will return the EXE's handle.  This won't work if it needs instance handles from other Dll's, child process's, etc.

If neither of these techniques work, post the code where you delcare the handle, export it, and import it.

0
 

Author Comment

by:rfaherty
ID: 1171570
No, the GetModuleHandle suggestion didn't work. It still returned a handle of 0x00400000 which when used in a .dll in the application produces Error Code 126 - The specified module cannot be found.
0
 
LVL 7

Expert Comment

by:faster
ID: 1171571
What you are trying to do is very strange.  I don't think you can export a function in the DLL.  GetProcAddress() only states that it can accept an handle of a dll, not exe.

Why not simply move the function to the DLL?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:nietod
ID: 1171572
Sorry, I mis-understood your question.  I thought the problem was in getting the handle in the Dll, not getting a procedure with it.  I'm surprised that GetProcAddress() doesn't work with an EXE, as EXE's and DLL's are very similar.  But maybe microsoft decided to prevent this, I've never tried.  

However if you can't move the procedure to the DLL, there are other options.
0
 

Author Comment

by:rfaherty
ID: 1171573
What are the other options ?
0
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
ID: 1171574
Without knowing more about your needs, I can suggest three ways.  There may be others that are more appropriate.  

1. You can pass a pointer to the EXE's procedure to the DLL when you call the DLL procedures that need to callback the EXE procedure.  

2. If passing an extra pointer is inconvenient, you could pass it just one time to a "registration" procedure in the DLL. The registration procedure would save the pointer in a global variable.  Of course, this requires that every EXE that uses the DLL must "remember" to register with the DLL.

3.  You could make the EXE export a pointer to the the procedure and the DLL import it.  (i.e. just the same way you handled the EXE's HINSTANCE, except with a pointer to a function).
0
 

Expert Comment

by:xitech
ID: 1171575
The module handle for the .EXE will always be 0x00400000 as this the base address that all .EXE files are loaded at.  There is no reason why  GetProcAddress() should not work unless thes function name you are passing is incorrect, remember that C++ programs export mangled names when using the __export directive. If this is the case you would need to export an unmangled name by including the function in a DEF files EXPORTS section e.g

EXPORTS
    MyFunction    @1

Jus.


0
 
LVL 22

Expert Comment

by:nietod
ID: 1171576
xitech, do you know for a fact that GetProcAddress() can work with an EXE's module handle?  I've never tried it.

If it does work then, rfahery you can use your original technique and export by procedure number as xitech suggested, or you can declare the exported procedure as extern "c", like

extern "c" {
   DllExp MyFunc()
   {
   }
}

This disables name decoration on the specified function so you only have to specify the regular (non-decorated) name where you import.

However, any of the techniques I suggested using procedure pointers will work regardless of whethor or not GetProcAddress() can be used on an EXE.  So, I would consider them carefully.
0
 

Expert Comment

by:xitech
ID: 1171577
The two following files demonstrate an EXE calling a DLL passing it the EXE's HINSTANCE or HMODULE (same thing in Win32).  The DLL then calls back to a function exported from the EXE. Sorry not to much error checking, but it proves a point.

// Example EXE File E.CPP
// Compile and link with :-
// CL E.CPP
#include <Windows.h>
#include <iostream.h>

typedef void (*MyFunc)( HINSTANCE exeHand );

void main(void)
{
    HINSTANCE hInst = GetModuleHandle(0);
    HINSTANCE Dll = LoadLibrary("d.DLL");

    MyFunc p = (MyFunc)GetProcAddress( Dll, "DLLFUNC" );
    p( hInst );
}

extern "C" void __declspec(dllexport) EXEFUNC(void)
{
   cout << "Hello its me, the EXE file again !\n" << endl;
}


// Example DLL File D.CPP
// Compile and link with :-
// CL D.CPP /LD
#include <Windows.h>
#include <iostream.h>

typedef void (*ExeFunc)( void );

extern "C" void __declspec(dllexport) DLLFUNC( HINSTANCE exeHand )
{
    cout << "Hi, in the DLL, Calling back" << endl;

    ExeFunc p = (ExeFunc)GetProcAddress( exeHand, "EXEFUNC" );
    p();

    cout << "Returned from EXE callback." << endl;
}

--End Of Listings--

Q.E.D :-)

Best Regards,
Jus.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

739 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