Solved

.exe HINSTANCE problem

Posted on 1997-10-16
9
1,048 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone 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 will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

622 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