views:

456

answers:

2

After a number of hours Googling, I think it's time to ask the experts. We have a legacy module (MS Visual C++ 6.0) that we are trying to port to VS 2005. A number of calling applications exist, so we're trying, if possible, to keep these backward-compatible.

Code-wise, this turned out pretty straightforward and a few hours of development eliminated all compiler errors and most warnings.

Then I came up against a few "unresolved external symbol" errors in the linking step, which seem to be subtle differences in the decorated name.

It turns out that one set of errors was related to time_t being a 64-bit structure in VS2005 -- defining _USE_32BIT_TIME_T fixed those three.

Now I am stuck with two remaining errors:

The function is defined as

int RC_STATE::my_function(UINT stateId, UINT period, UINT index, UINT paramtype, UINT dpindex, UINT managerId, UINT calctype, UINT status, double *p_val, long *p_isc, CTime *p_time)

It appears that under "old" Visual Studio, it was happy with the decorated name

?my_function@RC_STATE@@QAEHIIIIIIIIPANPAJPAVCTime@@@Z

But now, VS2005 wants to include the ATL namespace for the "CTime" parameter:

?my_function@RC_STATE@@QAEHIIIIIIIIPANPAJPAVCTime@ATL@@@Z

If I update my .DEF file with this new decorated name, it compiles & links... yay! Except as soon as I plop that DLL down with some code that used to work, it complains that it can't find the procedure entry point in the DLL (i.e. the one with the "old" structure, no namespace).

Any suggestions? Is there some sort of keyword, compiler directive that would allow me to tell the compiler not to put the namespace in the decorated name (I know that namespaces are good, but there is no conflict afaik with the CTime type that would need the namespace to resolve the conflict).

Are there any workarounds to get the decorated name to match the old format?

Many thanks in advance to any suggestions.

+3  A: 

There are actually two problems here. First, CTime is now in the ATL namespace, as you've found, but also CTime in VS2005 uses __time64_t internally, which is 64 bits, not 32 bits, and that isn't changed by defining _USE_32BIT_TIME_T.

So, even if you were to fix the namespace problem, if your application is compiled with VC6 and the DLL is compiled with VS2005 (or vice versa), passing CTime objects between these modules would almost certainly lead to data corruption problems due to the difference in memory layout.

In my view, the solution is to recompile all your code with VS2005, and use the 64-bit time_t throughout, consistent with CTime in VS2005 (i.e, don't use _USE_32BIT_TIME_T).

I hope this helps!

ChrisN
Thanks, I had a feeling this would be the "best" approach. I need to determine how practical recompiling all calling apps is. Thx!
+1  A: 

Another possibility would be to copy the old definition of CTime into your VS2005 project and use it on the parameter list of the function where you're trying to keep compatibility. Then convert between your back-compatible CTime parameter into the new ATL::CTime before processing. Old VC6 clients can call your back-compatible method.

Aidan Ryan
Also a good idea. I shall try that out hopefully not!
When you copy the definition, don't put it in any namespace, basically just pull the old definition straight into your new project.
Aidan Ryan