Compile with different versions of Visual Studio

G

Guest

Hello,

Likely this has been asked before...

We have a library (in DLL form) that we distribute. The interface to the
library is all C, but within the library it uses C++ in many places.

Traditionally we've built our library with VC 6. We are considering moving
to VS .NET 2003 or VS 2005. However, we'd like to retain the ability to link
applications with the library when the application is still built with VC 6.

What issues are there with regard to linking in versions of the C runtime
library? E.g. Are the object files built with VC 6 going to try to link to
the VC 6 CRT, while the object files in the library built with VS 2003 or VS
2005 going to try to link with a different CRT?

Thanks.
 
J

Jochen Kalmbach [MVP]

Hi cantatahost!
We have a library (in DLL form) that we distribute. The interface to the
library is all C, but within the library it uses C++ in many places.

Traditionally we've built our library with VC 6. We are considering moving
to VS .NET 2003 or VS 2005. However, we'd like to retain the ability to link
applications with the library when the application is still built with VC 6.

What issues are there with regard to linking in versions of the C runtime
library? E.g. Are the object files built with VC 6 going to try to link to
the VC 6 CRT, while the object files in the library built with VS 2003 or VS
2005 going to try to link with a different CRT?

1. You should link against the static version of the CRT (then you will
have no dependency to a special version of the CRT DLL)

2. You must have only C-Funktion interfaces! No dependecy to STL/MFC/ATL
in your Dll-interface!


Then it should be fine. You could also build the DLL with VC8 and link
it with VC6...

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
G

Guest

We have a library (in DLL form) that we distribute. The interface to the
1. You should link against the static version of the CRT (then you will
have no dependency to a special version of the CRT DLL)

2. You must have only C-Funktion interfaces! No dependecy to STL/MFC/ATL
in your Dll-interface!

Then it should be fine. You could also build the DLL with VC8 and link
it with VC6...

Is it required to do both #1 and #2 in order for it to work? Or will either
#1 or #2 be fine?

For #2, is what I said above about how our library is written sufficient?

For the third paragraph, I don't understand whether you're saying this will
work only if I do #1 and/or #2, or if it will work all the time. Could you
please clarify?

Thanks.
 
B

Bruno van Dooren

We have a library (in DLL form) that we distribute. The interface to the
Is it required to do both #1 and #2 in order for it to work? Or will
either
#1 or #2 be fine?

1 is not a requirement, but you have to distribute the appropriate runtime
with your dll
if you don't link against the static runtime.
For #2, is what I said above about how our library is written sufficient?

at first glance it seems sufficient.
For the third paragraph, I don't understand whether you're saying this
will
work only if I do #1 and/or #2, or if it will work all the time. Could you
please clarify?

Jochen pointed out that you can indeed build your dll in VC8 and use it in
VC6.

one other thing that is also a definite requirement is that your dll has to
respect memory ownership.
see this article for more detailed explanation.
http://vcfaq.mvps.org/lang/9.htm

if your dll has only C style interfaces, and respects memory ownership,
you can build your dll in any VC version, and use it for building an
application in any VC version.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
T

Tamas Demjen

cantatahost said:
Is it required to do both #1 and #2 in order for it to work? Or will either
#1 or #2 be fine?

Both. #1 basically says that you can't mix runtime libraries. VC6 has a
different C runtime library (including memory manager) than VC8,
therefore you can't share the same RTL between the two modules. You have
to treat VC6 and VC8 as two completely incompatible environments, as if
they were developed by a different company.

It doesn't mean that you can't use dynamic RTL for your application, but
you can't share the same dynamic RTL between modules compiled with
different compilers. For example, if you use MFC from both the DLL and
the application, they were be completely independent copies of the MFC
library that have nothing to do with each other.

#2 states that only C-style interfaces are guaranteed to be
cross-compiler compatible. For example, you can always call a function
like this between independent modules:

int f(const char*);

However, a function like this is not compatible between VC6 and VC8:

int f(const std::string& s);
or
int f(const CString& s);

It doesn't mean you can't do object-oriented programming and share C++
classes between compilers, but you must fully understand what you're
doing if you choose to do so. I have a small article about this, which
is largely unfinished, but it contains a lot of information about
sharing classes between completely different compilers (even Borland and
Microsoft):

http://tweakbits.com/articles/dll/index.html

There's no easy way to tell what you can do, but one can certainly list
what you can't do in your cross-compiler DLL interfaces:

1. You can't use MFC (like CString), ATL, STL (std::vector, std::string)
in any of the functions that you plan to call between compiler
boundaries. VC6 and VC8 have completely independent implementation of
these libraries. Classes like CString, CWindow, std::string are not
byte-compatible between different versions of the compiler.

2. VC6 and 8 have totally different memory managers. Anything allocated
in a module must be deallocated in the same module. So if your DLL
allocates memory and returns pointer to it, you must not free that
pointer from you application. You DLL must also export a function that
frees the memory it allocated.

3. extern "C" __stdcall functions are the most portable, if they don't
have anything else but basic native C types in their signatures. Then
they can even be called from different languages, such as Pascal or
Fortran. __cdecl functions are also fine between C/C++ compilers.

4. You're not allowed to throw exceptions between compiler boundaries.
Your DLL must catch every exception and translate them into error codes.
Exception handling is implemented differently in VC6/8, so if your DLL
throws, you won't be able to catch it in your application.

5. I'm sure the list could go on. Anything that involves C++ features is
not guaranteed to work, unless it's implemented very carefully. If you
read my article, you'll learn how to use C++ classes between different
compilers using virtual functions to bind interface to implementation.
This (usually) works between different compiler vendors too. However,
you're still not allowed to use MFC and STL classes between the calls,
and you must still allocate and deallocate memory from the same module.

I've developed a safe string and vector class that you can use to pass
information between compiler boundaries. These classes are safe, because
they maintain an allocator in addition to the data, to ensure everything
is freed where it was allocated. If you link the exact same code to both
compilers, you should be able to use my classes across compilers, but I
provide my code without any warranty. If you don't understand what
you're doing, you can still very easily crash your program. Any data
shared between DLL modules assumes that you use the same data alignment,
otherwise binary compatibility can not be ensured.

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top