This section contains a list of common problems encountered when developing 3ds Max plug-ins in .NET. These particular issues were chosen for discussion here because they tend to have limited documentation available and were more difficult to debug or resolve. Other common issues are not listed here because they are covered by resources elsewhere, either in the MSDN documentation, in the 3ds Max SDK documentation, or in most .NET books.
Generally, warning LNK4248 is signalled when the C++ / CLI compiler must create an empty class wrapper for a forward-declared type. This is not a problem if the class definition is not required in the module. The warning can be suppressed by either including the full class definition for the given type or by explicitly creating an empty class definition. SeeSceneExplorerExtensionClassDesc.cpp in the how-to sample project for an example.
A most common cause for a crash of 3ds Max when a .NET plug-in is being loaded or unloaded, is due to an exception being thrown and not caught. 3ds Max cannot handle an exception thrown during DLL loading or unloading. For .NET plug-ins, an exception is thrown for any call into managed code before the CLR is loaded or after the CLR is unloaded for the given DLL. In other words: an exception is thrown for any managed code executed from DllMain. The solution is to perform initializations in LibInitialize and clean-up in LibShutdown. Often a call to the CLR occurs for any static object instance in the DLL. Temporarily setting the /NOENTRY linker option under: Configuration Properties -> Linker -> Advanced -> No Entry Point will help find any statically allocated instances. See LibShutdown in dllmain.cpp in the how-to sample project for an example.
Another common cause of 3ds Max crashing on start-up is the presence of multiple copies of the .NET assemblies in various start-up directories. For example, if Autodesk.Max.dll is present in both the 3ds Max application directory and in bin/assmblies, 3ds Max will crash. Make sure Copy Local is set to False for assembly references in your .NET project if you have set the project's build output directory to the 3ds Max /bin/assemblies directory.
Native types are private by default in C++/CLI. If a public function takes a private type as a parameter, references to this function from outside the assembly will generate error C3767. The solution is to mark the native type being used as public using a #pragma make_public(type) directive. See NativeInclude.h in the how-to sample project for an example.
When writing a .NET plug-in, it is neccessary at one point to call managed code, from native code. You can call an managed class that is not garbage collected (e.g. it is not a " ref class "), but you can only call methods that have no managed types in the signature. If a managed type is in the signature, the calling convention for that methods implicitly becomes "__clrcall".
This linker error occurs if a custom metadata attribute is not applied consistently to a type. This occurs if a native type is marked using a #pragma make_public directive in one translation unit, but included without the directive in another translation unit. To avoid this problem, the 3ds Max SDK development team adopted the habit of grouping all of a C++/CLI assembly's native includes in a single header file and applying all metadata directives in that file. See NativeInclude.h in the how-to sample project for an example.
It is possible in some circumstances for deadlock DLL initialization, a situation sometimes called loader lock. Resolving this problem is described on MSDN at http://msdn.microsoft.com/en-us/library/ms173266.aspx.