Odd Linker Error (LNK2019) With VS 2005 When Using Dll Built with VS 6.0

I'm new to Visual Studio 2005, and I'm encountering an odd linker problem.  Suppose I have a dll called "mydll" that contains a declaration (and implementation) of the following function:
--------------
#ifndef MYDLL_EXPIMP
  #ifdef MYDLL_EXPORTS
    #define MYDLL_EXPIMP __declspec(dllexport)
  #else
    #define MYDLL_EXPIMP __declspec(dllimport)
  #endif
#endif
void MYDLL_EXPIMP Test(WCHAR *wszValue);
--------------
If I build this dll using Visual Studio 6.0 and then attempt to build a separate application in Visual Studio 2005 that utilizes that dll (and its library file), I get an error like the following:

1>ApplicationFile.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl Test(wchar_t *)" (__imp_?Test ....(more)...

If I build the dll using Visual Studio 2005, the build-time error goes away, but my application crashes at runtime due to some bizarre threading loop that leads to a stack overflow.

I've never seen anything like this and my understanding is that library files (.lib) are supposed to be standards-based and fully compatible between versions and brands of development environments.

Can anyone tell me what's going on here?


mydll.h
 
#ifndef MYDLL_EXPIMP
  #ifdef MYDLL_EXPORTS
    #define MYDLL_EXPIMP __declspec(dllexport)
  #else
    #define MYDLL_EXPIMP __declspec(dllimport)
  #endif
#endif
 
void MYDLL_EXPIMP Test(WCHAR *wszValue);
===========
mydll.cpp
 
void MYDLL_EXPIMPT Test(WCHAR *wszValue)
{
  return;
}
===========
Consumer application includes header file #include where function is used and project references mydll.lib for linking.

Open in new window

LVL 1
dshockeyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Infinity08Commented:
Try these :

mydll.h
---------
 
#ifndef MYDLL_EXPIMP
  #ifdef MYDLL_EXPORTS
    #define MYDLL_EXPIMP __declspec(dllexport)
  #else
    #define MYDLL_EXPIMP __declspec(dllimport)
  #endif
#endif
 
void MYDLL_EXPIMP Test(WCHAR *wszValue);


mydll.cpp
------------

#define MYDLL_EXPORTS
#include "mydll.h"
 
void MYDLL_EXPIMP Test(WCHAR *wszValue)
{
  return;
}
===========
0
dshockeyAuthor Commented:
In the project for the dll, MYDLL_EXPORTS is already defined.  I forgot to include one critical piece of information: The error only occurs if a method has unicode string pointer for a parameter.  So, for example:
void MYDLL_EXPIMP TestA(char *szText); <-- no problem
void MYDLL_EXPIMP TestW(WCHAR *wszText); <-- problem
0
Infinity08Commented:
I'm not an expert on Visual Studio, but I wouldn't be surprised if there are compatibility isses between 6.0 and 2005. I'll let someone else with more knowledge about this take over ;)
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

Infinity08Commented:
Just one more thing maybe : I assume you checked for typo's between the .h and the .cpp file ? Like the one you had in the code you posted : MYDLL_EXPIMPT vs. MYDLL_EXPIMP
0
evilrixSenior Software Engineer (Avast)Commented:
>> error LNK2019
I'm just wondering (guessing!), should the __declspec come before and not after the function return type?

e.g MYDLL_EXPIMP void Test(WCHAR *wszValue)

http://msdn2.microsoft.com/en-us/library/9h658af8(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/dabb5z75(VS.80).aspx

>> If I build the dll using Visual Studio 2005, the build-time error goes away, but my application crashes at runtime due to some bizarre threading loop that leads to a stack overflow.
I strongly suspect this is unrelated to the linker issue. Can you provide any more information on this? Code example maybe?

>> my understanding is that library files (.lib) are supposed to be standards-based and fully compatible between versions and brands of development environments
Where ever did you get that idea? Some compilers aren't even compatible with themselves :)

-Rx
0
evilrixSenior Software Engineer (Avast)Commented:
>> my understanding is that library files (.lib) are supposed to be standards-based
There is no documented standard for the Application Binary Interface for C++. It is completely and utterly down to the vendor to pretty much make it up as they go along. For example, each compiler is free to implement name decorating as the vendor sees fit. This often doesn't even work between different versions of the same compiler! Try building C++ code on VC6.0 and then try and link to in on VC7.0 or greater and you'll find it probably won't link due to unresolved names. DLL's go someway to getting over this; however, if you are linking to the .lib DLL stub file to implicitly link to the DLL then this could be why the library you build on VC6.0 won't work with VC7.0! If so, you can get around this by explicitly loading the DLL using LoadLibrary(). You may be able to avoid explicit linkage if you can export your functions using C rather than C++ linkage. You need to wrap the declaration of your exported functions in an extern "C" block to give them C (undecorated) rather than C++ (decorated) linkage.

Example (untested) below: -

Some useful links that might help.
http://en.wikipedia.org/wiki/Application_binary_interface
http://msdn2.microsoft.com/en-us/library/253b8k2c.aspx
http://msdn2.microsoft.com/en-us/library/ms235636.aspx
http://msdn2.microsoft.com/en-us/library/d91k01sh(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/28d6s79h(VS.80).aspx
mydll.h
 
#ifndef MYDLL_EXPIMP
  #ifdef MYDLL_EXPORTS
    #define MYDLL_EXPIMP __declspec(dllexport)
  #else
    #define MYDLL_EXPIMP __declspec(dllimport)
  #endif
#endif
 
extern "C" // Ensure the function has C linkage (it is exported undecorated).
{ 
   void MYDLL_EXPIMP Test(WCHAR *wszValue);
}
===========
mydll.cpp
 
void Test(WCHAR *wszValue)
{
  return;
}
===========
Consumer application includes header file #include where function is used and project references mydll.lib for linking.

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dshockeyAuthor Commented:
Evilrix,
That answered my question.  The application crash that I described in the original ended up being because of an unrelated problem in my code that went undetected until I used VS 2005.

As for the linker problem, this raises some very interesting problems that I'll need to address.  The name decoration problem is one that I can't fix by using _stddecl because the methods that are having problems employ variable argument lists, so I need the caller to clean up the call stack after a function completes and returns.  However, because the name decoration changes between versions of Visual Studio, at the time I move my application to VS 2005, I'll have to recompile all dependent dlls at the same time that I do the main application.  And it now seems that if I was dependent on a third-party dll with a VS 6.0 library file, I'd be SOL. (or I'd have to do explicit run-time loading of the library and its methods)

Thank you for the info on this!
0
dshockeyAuthor Commented:
Thank you!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.