Why do 3ds Max plug-ins need to be built with a specific version of Visual C++? - visual-studio

The requirements listed in the 3ds Max SDK state that plug-ins for 3ds Max 2011 must be built with Visual C++ 9.0 (Visual Studio 2008).
If I create a DLL with a different version of Visual C++, won't the binary be identical? Is this simply a matter of choosing the right compiler settings?
What problems will I run into if I try to build a plug-in using Visual C++ 2010 (Visual Studio 2010)?

I don't know specifically for 3ds Max, but the usual reason is the C Runtime library. If the host application uses the DLL version of the CRT, then plugins will also need to use the same version.
Otherwise, imagine the case where your plugin creates some memory using malloc(), and passes it to the host application, which uses it and then calls free(). If your plugin and the host application are using different CRTs, the host's call to free() will fail or crash because it wasn't the host's CRT that malloc()ed that block of memory.

The binary won't be identical but the binary interfaces should be, which is what you need.
The reason you can't use VS2010 is because it is not yet production quality. They think you should wait for VS2010 SP1 at a minimum.
You think they are just being obstinate and stubborn, eh? Ruining all your fun. They have reasons. Good ones.
Because of bugs like this:
https://connect.microsoft.com/VisualStudio/feedback/details/565959

I use both visual studio 2008 and 2010 for plugin development.
Only difference I've seen is that the user need the vs c++ runtime version for 2010\2008.
But there might be pitfalls - but I have not encountered any problems with it yet.

C++ doesn't have a standardised binary interface. The compiler "mangles" each symbol name (i.e. each function or static data) to include information about namespaces and signature, so that namespaces, argument overloading, &c. can work. Each compiler is free to decide how to do this. Different MSVS compiler versions do name mangling in different ways, so in general you can't link a C++ library compiled with 2005 and a library compiled with 2008 together: this includes loading a 2008 DLL from a 2005 executable (for example). You can do this if the interface between the libraries is C, as long as the relevant functions are marked with extern "C" to prevent name mangling. And in practice the differences are not always that great: for example, I never had trouble using VS2005 SP1 to compile a library for 3ds Max 9, which supposedly requires VS2005 with no service pack.
Microsoft is trying to fix this incompatibility, so in VS2010 they introduced an option, so VS2010 can produce binaries compatible with VS2005 programs or VS2008 programs (maybe some earlier versions too, I forget). If you have to create a plugin to work with multiple 3ds Max versions, and you don't get caught out by any VS2010 bugs, this is probably a good option. Also, the Intel C++ compiler has a mode where it produces binaries that are compatible with an MSVS version of your choice, which might be a better option for you if it's for hobby use or you can afford the slightly expensive price tag. (They achieve this by copying the way MSVS does name mangling.)

Related

Why does my application require Visual C++ Redistributable package

I'm writing a simple C++ application in Visual Studio. It also has a setup project.
It works well on my development machine, but when I'm installing this application on user's machine it requires Visual C++ Redistributable Package. I'm wondering why does my application require C++ Redistributable? Standard C++ runtime library is shipped with Windows, isn't it?
The only version of the C runtime library which is shipped by Microsoft with most of 32 bit Windows versions is msvcrt.dll. This library provides a typical set of library functions required by C and C++ programs. These include string manipulation, memory allocation, C-style input/output calls, etc.
Visual Studio 6.0's compiler links against this library, so if you are developing in VS 6.0 you shouldn't encounter any problems on most users' machines.
However, if you are developing in VS 2005, VS 2008, VS 2010, VS 2012, VS 2013 or VS 2015, you have to distribute additional C runtime libraries along with your application. This is because their compilers link against msvcrt80.dll, msvcrt90.dll, msvcrt100.dll, msvcrt110.dll, msvcrt120.dll and msvcrt140.dll respectively, which are not shipped with Windows.
Solutions:
Possible solution is to link statically with runtime library, but it may cause a lot of problems in case you have both .exe and .dll in your application. Don't do that.
To be more specific, I'll allow myself to quote a part of this answer:
Using /MT is risky if you create DLLs as well as an EXE. You'll end up
with multiple copies of the CRT in your program. This was especially a
problem with earlier versions of VS where each CRT would get its own
heap, not so much with VS2012. But you can still have ugly runtime
problems when you have more than one "errno" variable for example.
Using /MD is highly recommended to avoid such lossage.
Another possible solution is to require an appropriate Microsoft Visual C++ Redistributable package to be installed on the user's machine.
It may be done by specifying this requirement in prerequisites property in your setup project.
Also, you can distribute the runtime dll by including in your setup project the appropriate "merge module". In this case don't forget to add the appropriate "policy merge module" to avoid errors caused by incorrect runtime version.
Finally, you can just put required DLLs in the same folder in which your application is installed.
Further reading:
"Redistributing Visual C++ Files" - Official MSDN documentation
Even though some comments said that «link statically with runtime library, but it may cause a lot of problems when you have both .exe and .dll in your application.» this is NOT TRUE. First we DON'T statically link DLLs! We statically link OBJs and LIBs. LIBs are static libraries; DLLs are dynamic libraries, and you may choose to use LIBs (static) or DLLs (dynamic). It's entirely up to you to choose. The ONLY drawback (for the DLL fans) is that if you want to update one library, you need to compile and link again. I personally deploy ALL my software static linked and because of that I earn the bonus of don't even need installers. The software I develop is 100% portable (a feature that in the pre-installer era was general procedure), and the final user is free to simple COPY from one folder to another or even from the hard drive to flash drive (or vice-versa). The error message «DLL not found.» simply doesn't exist ... NEVER.
Some folks think of statically linking as toy software: WRONG! I can write a full featured application that connects to a DBMS (Oracle, SQL Server, ...) or any other kind of application.

How can I link a 2010 generated DLL in Visual Studio 2008?

I have a DLL generated from Visual Studio 2010, but I need to link it to a 2008 project that needs to remain 2008 for various other reasons. Anyone run into similar trouble or have advice?
VS2010 is .NET 4.0
VS2008 is .NET 3.5
So the answer for your question is NO because if the dll is making use of any of the specific .NET 4 features, it wont get executed in your 3.5 environment. Also it may happen that the assembly mapping is different in both the .NET version and that may become one of the reason for the 4.0 dll not getting executed in 3.5 env.
I am not sure, but you may look at COM Interop features. May be it can help you in achieving what you want. But it would be too messy !!
Dynamic-Link libraries (DLL) are an integrated part of the Windows platform from its very beginning. DLLs allow encapsulation of a piece of functionality in a standalone module with an explicit list of C functions that are available for external users. In 1980’s, when Windows DLLs were introduced to the world, the only viable option to speak to broad development audience was C language. So, naturally, Windows DLLs exposed their functionality as C functions and data. Internally, a DLL may be implemented in any language, but in order to be used from other languages and environments, a DLL interface should fall back to the lowest common denominator – the C language.
http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
Standardized C style interface, should be ok, though that pertains only to non managed C++.

How can i compile a DLL so it works with VS2005/2008/2010

I have a C++ dll. Is there a way to compile it so that it can be used with VS2005/2008/2010 instead of me having to do 3 different builds?
Thanks
You can generally "use" a C++ dll with any version of Visual Studio, if you're just linking to it.
However, when your dll is compiled, it will be targetted to a specific version of the C++ runtime, so end-users of your program will need to have that runtime (Visual C++ redistributable package) installed on their PC. So if you use a dll built by VS2005 and an exe built by VS2010, your end user will have to install both the 2005 and 2010 redistributable packages. The same generally goes for other libraries if you use them (MFC, etc)
If you do this, you will also have to be careful about memory allocation - memory allocated in one runtime version cannot be safely deallocated by another. So anything that your dll allocates must also be deallocated by the dll, and anything allocated by your exe must not be deallocated by the dll.
As a result, most people will rebuild the dll with the same version of VS as they build the rest of their program in, to minimise the compatibility issues - ultimately it's much easier to build in each verison of VS than to sort out all the issues involved in not doing so.
(Hint: You can run VS from the command line and get it to build a project/solution, so it's a 5 minute job to write a batch script that will automate building all three variants in one go)
The version of visual studio in use doesn't make a difference as to whether a given assembly can be referenced.
The only thing that matters is what version of the framework the assembly was compiled against.. Assuming it's a .net assembly anyway.
Regardless, it's common practice to provide versions compiled against each framework rev (2.0, 3.5, and 4.0) anyway.
However, if you are compiling an unmanaged c++ dll; then just provide a 32 bit and a 64 bit version of that dll. In this case the .net version in use (and visual studio version for that matter) is immaterial.

Managed code in Visual Studio

Is it possible to switch off managed code (and switch on unmanaged code) for c++ coding, so that programs (exes) made are run direct to native machine code in Visual Studio 2008?
Also, is it true that after the first time a .net (managed) exe runs (say written in C#) the exe gets converted to a native code one (like the old c++ ones pre .net)? Or is there a way to make it compile direct to native code if it was written in C#?
The answer to both of these questions is yes.
You can create unmanaged c++ code projects in VS which do not need .Net. You can also link unmanaged C++ code to managed C++ code and (sort of) get the best of both worlds - although the matching of calling parameters between the to systems is interesting.
You can also use the ngen .Net utility to pre-compile .Net projects to pure code. However in doing so you loose some flexibility. The JIT compiler will take account of local capabilities when compiling a .Net project. So if you distribute a .Net project as generated by VS then ngen on the local machine that runs the program will do the compiliing. However if you use ngen on your machine the precompiled code will be tied to the processsor capabilities of your system.
As per Joel's comment. regardless of using ngen or not, you still need .Net framework on the target machine.
In thinking about it, the use of ngen to pre-compile a .Net project probably is no worse than compiling an unmanaged c++ project to native code.
To do what you want for C#, you would use ngen.exe, which comes with the C# compiler. You run that command on the image, and it gets added to the GAC as native code.
As far as i know, you can switch temporarily to unmanaged code, i.e. using unmanaged variables etc. by marshaling. Take a look here: http://msdn.microsoft.com/de-de/library/bb384865.aspx

Can a app built with Visual C++ 6 use a DLL built with Visual Studio 2008?

I'm developing an SDK, and we have clients that are still coding with VC++ 6, while others use Visual Studio 2005 and others with 2008.
Currently, we build several flavors of our SDK, where we build the exact same source code with each of those compilers. I want to find out if that is really necessary. Is it safe to build our SDK (which takes the form of DLLs) with VS2008 and expect our clients who use VC++ 6 to be able to use it without problems?
Depends. Does your DLL depend on the VC runtime, MFC or ATL? If so, your clients will have to distribute those dlls. Does your dll export C++ structs/classes/functions? There is no standardized ABI for C++, so they may or may not work with other compilers. If your dll only exports extern "C" {} style, you'll be fine.
It is pretty safe if you'll not allow client's program to delete memory that was allocated in your SDK. And vice versa.
If the DLL has a pure C API, your executable will never release any resource allocated by the DLL (and vice versa), then it should work.

Resources