Question

Here's a puzzler that I can't find an answer to (here at SO or other sites). I'm a newbie to SO, but I'm trying to learn quickly.

I need to change the name of my dll Entry Point procedure from

int subCreatePipe()

to

int subCreateNewPipe()

But the launching program dies when I do that.

The specific error is:

"The procedure Entry Point subCreateNewPipe could not be located in Dynamic Link Library myPipe.dll"

The settings I'm running on are:

  • Windows 7
  • MS Visual Studio 2010
  • C++ Win32
  • Unmanaged (no CLI)
  • MBCS

    • I created a "myPipe.dll" (using above settings) to test my ability to create a dll and open a pipe.
    • I created a "TestPipe.cpp" (using above settings but with Win32 console) so I can run a program that will link to the dll and display some results for me.
    • (I also have another program that will send something to the pipe.)

Now here's the kicker:

  1. I created the dll with a procedure called int subCreatePipe() in it.
  2. I compile it with success.
  3. I move the release files to my TestPipe project "Lib" subfolder.
  4. In TestPipe.cpp I have a line to call to the procedure:

    x = subCreatePipe();
    
  5. I compile the TestPipe.cpp and run the release "TestPipe.exe" and it runs perfectly. It finds the entry point of subCreatePipe.

But I need to rename the DLL Procedure to subCreateNewPipe to adhere to a naming convention that I have no control over.

  1. I rename the procedure in myPipe.dll to int subCreateNewPipe()
  2. I compile it with success.
  3. I move the release files to my TestPipe project "Lib" subfolder. (deleting the old files)
  4. In TestPipe.cpp I change the call to the procedure to:

    x = subCreateNewPipe();
    
  5. I compile the TestPipe.cpp and run the release "TestPipe.exe" and it dies (with the error given above).

If I go back and change the DLL Procedure name to subCreatePipe, it will run again. If I go back and change it to subCreateNewPipe, it dies again. The only thing I'm doing differently is changing the Entry Point Procedure name.

So my questions are:

  1. Is there a way to rename an Entry Point Procedure in VS 2010?
  2. Should I be using DLLMain() even though I'd just leave it blank? (This seems bad form.)
  3. Is there some hidden switch I'm missing?
  4. What is really going on with the Linker?
  5. Is there name mangling going on?
  6. Or is there something else that can't be be changed after you compile a project for the first time?

A few other things I tried (that still give the same results of "the first way working" but "the second way failing"):

  • I tried using __stdcall

    int __stdcall subCreatePipe() // works 
    int __stdcall subCreateNewPipe() // doesn't work
    
  • I tried using __declspec(dllexport)

    ifdef X_EXPORT_FLAG  
    #define DLL_IMPORT_EXPORT __declspec(dllexport)  
    else  
    #define DLL_IMPORT_EXPORT __declspec(dllimport)  
    endif
    
    X_EXPORT_FLAG int __stdcall subCreatePipe() // works
    X_EXPORT_FLAG int __stdcall subCreateNewPipe() // doesn't work
    
  • I also tried using a .DEF file to define the procedure name to the Linker.

    int subCreatePipe() // works 
    int subCreateNewPipe() // doesn't work
    

(In all examples I change the TestPipe.cpp code to call the proper procedure name.)

If you can't tell, I'm a bit OCD about trying to figure out the way to get this to work.

I'm now going to go create a new Win32 console app to call the dll (something I should have done 24 hours ago.) However, I'm still very curious why I couldn't change the Entry Point Procedure name. Any insights into why it can't be done, better coding techniques, or how to get around this linker problem would be gratefully welcomed.

Était-ce utile?

La solution

SOLUTION:

In Unmanaged C++, the DLL's don't get cleaned out of the "Release" folder the way they do in Managed C++. You must physically move your new DLL into the "Release" folder of your application program each time you make changes to your DLL.

I learned how to deal with updating DLL's in Managed C++ where all you have to do (in your application program folder) is clear out your old DLL library subfolder and copy in the new Release of the changed DLL's into that empty library subfolder. When you "Clean and Rebuild" the application that calls those DLL's, the Managed VS2010 C++ will delete the old DLL's out of the "Release" folder and copy the new DLL's from the library subfolder into the applications "Release" folder. It nicely keeps your DLL's up to date.

In Unmanaged C++, the "Clean and Rebuild" does not delete your old DLL's out of the application's "Release" folder. And it doesn't copy the new DLL's over from your library subfolder either. So even though I thought I was placing my new DLL's in a folder that my program could find them, they were not being copied like they are under Managed C++.

When Michael Burr gave me the link /dump /exports myPipe.dll tools, I was able to see the Time Stamp of the DLL and the procedures that were available. (In my case it was the first DLL build which only had one procedure.) It was obvious it was an old DLL and not the current one.

This explains why the app always ran with the old procedure name. However, when compiled with the new procedure name, it gave a procedure Entry Point error because the app was only able to find the old DLL (in which the new procedure name didn't exist).

Thanks again! :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top