• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1058
  • Last Modified:

.exe HINSTANCE problem

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
rfaherty
Asked:
rfaherty
  • 4
  • 2
  • 2
  • +1
1 Solution
 
nietodCommented:
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
 
rfahertyAuthor Commented:
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
 
fasterCommented:
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
nietodCommented:
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
 
rfahertyAuthor Commented:
What are the other options ?
0
 
nietodCommented:
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
 
xitechCommented:
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
 
nietodCommented:
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
 
xitechCommented:
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

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 4
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now