Can a single process load/use mscvr100.dll and msvcr110.dll without causing problems? - visual-studio-2010

An mixed-mode C++ application is built using VS2012, it references the managed DLL Noesis.Javascript.dll (which I believe was built with VS2010) which in turn links at runtime with msvcr100.dll.
I have observed a crash which seems to show the code within the Noesis.Javascript.dll calling library functions from VS2012's msvcr110.dll.
Is it possible to run a single process using two different versions of the C++ runtime libraries or is what happening here the likely cause of the problem? What is the alternative?

As mentioned for instance in this answer, it is practically impossible to combine these binaries. The crash is probably caused by the incompatiblity.
You could try the following: Project Properties -> General -> Platform Toolset: Visual Studio 2010 (v100).

It is possible to use both runtime DLLs in the same process, but to do so safely requires great care to ensure that no objects from one are used in the other.

Related

How to use VS2010 built dlls in VS2008

In my work we have VS2008.
Some partners in the project I work, use VS2010 (can't use VS2008)
They have to build a dll based and I have to use that dll in my framework...
I managed to build the main app and link the dll's.
the app starts, and objects from the VS2010 dll's are created,
but the app crashes when i try to delete these objects...
Windows has triggered a breakpoint in app.exe. This may be due to a
corruption of the heap, which indicates a bug in app.exe or any of the
DLLs it has loaded.
Have you any ideas on how to fix this?
Your co-workers' DLLs are linked against VS2010's runtime library. Your code is linked against VS2008's runtime library.
When you call some function from the VS2010 dll to allocate a new object, it will be allocated on that library's heap. When you call "delete" on that object, VS2008's runtime library will try to free it from its own heap. Since they're different, you get that error.
If you're going to mix runtimes like that, you need the VS2010 dll to expose free()-style functions (not just C++ destructors) for each type. There are other things you should be very careful with when mixing runtime libraries like that, such as using STL containers, or any sort of "copy-on-write" objects. In general, it's easier to avoid it.
Object that was allocated in dll or in an exe should be deallocated in same place. You need to talk about that with your partners. For the goal may be used overloading of allocating and deallocating operators http://www.cprogramming.com/tutorial/operator_new.html

Is there a way to join (link?) a managed (.net) dll at compile time?

I'm building a project which consists of two .net executables, and a class library with common components that the two executables share. For ease of distribution, I was hoping to be able to distribute the two executables without distributing the dll (grab & run distribution).
Is there any way to have visual studio compile the contents of the dll into each executable without manually copying the classes into each project (and thereby replicating the code in more than one place)?
Don't make it a DLL. Make it a static library instead.
Digging around on SO I found a duplicate question which stated the problem quite a bit more clearly than I did.
ILMerge seems to be the solution.
Static Linking of libraries created on C# .NET

Avoid loading .Net Dlls in a C++/CLI project?

I have a project written in C++/CLI. Some of the types there are in managed code, and some are in completely native code. Let's say I have the produced DLL on a machine that dosen't have any version of the .Net framework installed, is there a way that another, native application will link with my "mixed-mode" Dll and use only the native types? I've noticed that the minute I add the "/clr" switch, my Dll automatically depends on several .Net Framework Dlls (mscorjit, mscoree etc.), and when I actually try to use the 100% native types defined in it, the application still tries to load those .Net Framework Dlls (even though I don't use the framework in that part of the code).
So, is it possible to avoid loading those Dlls in such case? (as I see it, the other option is to create another, native project, that will contain all of the native types, without the managed ones).
Thanks
No. When you load a mixed mode assembly (/clr), right after DllMain runs, the .cctor runs and initializes the framework, if it hasn't already been setup for the application.
Without this, there would be a big hit as soon as you called a function that required a managed API. For details, see "Initialization of Mixed Assemblies" on MSDN.
The best option would be to make your native API a separate DLL, and have the mixed mode assembly a separate project, so you can load it separately if required.

Can I use a Visual Studio 6 compiled C++ static library in Visual Studio 2008?

Is it possible to use a C++ static library (.lib) compiled using Visual Studio 6 in Visual Studio 2008?
It really depends. Does the lib expose only 'extern "C"' functions where memory is either managed by straight Win32 methods (CoTaskMemAlloc, etc) or the caller never frees memory allocated by the callee or vice-versa? Do you only rely on basic libraries that haven't changed much since VS 6? If so, you should be fine.
There are 2 basic things to watch for. Changes to global variables used by 3rd-party libraries, and changes to the structure of structs, classes, etc defined by those 3rd-party libraries. For example, the CRT memory allocator has probably changed its hidden allocation management structures between the 2 versions, so having one version of the library allocate a piece of memory and having another free it will probably cause a crash.
As another example, if you expose C++ classes through the interface and they rely on MS runtime libraries like MFC, there's a chance that the class layout has changed between VS 6 and VS 2008. That means that accessing a member/field on the class could go to the wrong thing and cause unpredictable results. You're probably hosed if the .lib uses MFC in any capacity. MFC defines and internally uses tons of globals, and any access to MFC globals by the operations in the .lib could cause failures if the MFC infrastructure has changed in the hosting environment (it has changed a lot since VS 6, BTW).
I haven't explored exactly what changes were made in the MFC headers, but I've seen unpredictable behavior between MFC/ATL-based class binaries compiled in different VS versions.
On top of those issues, there's a risk for functions like strtok() that rely on static global variables defined in the run-time libraries. I'm not sure, but I'm concerned those static variables may not get initialized properly if you use a client expecting the single-threaded CRT on a thread created on the multi-threaded CRT. Look at the documentation for _beginthread() for more info.
I shouldn't think why not - as long as you keep the usual CRT memory boundaries (ie if you allocate memory inside a library function, always free it from inside the library - by calling a function in the lib to do the freeing).
this approach works fine for dlls compiled with all kinds of compilers, statically linked libs should be ok too.
Yes. There should be no issues with this at all. As gbjbaanb mentioned, you need to mind your memory, but VS2008 will still work with it. As long as you are not trying to mix CLR, (managed) code with it. I'd recommend against that if at all possible. But, if you are talking about raw C or C++ code, sure, it'll work.
What exactly are you planning on using? (What is in this library?) Have you tried it already, but are having issues, or are you just checking before you waste a bunch of time trying to get something to work that just wont?
Sure it'll work.
Are you asking where in VS2008 to code the references?
If so, go to proj props -> Linker -> Input on Configuration properties on the property pages. Look for "additional dependencies" and code the .LIB there.
Go to proj props -> Linker -> General and code the libs path in "Additional Library Directories".
That should do it!!
There are cases were the answer is no, when we moved from VS6 to VS2k5 we had to rebuild all our libraries, as the memory model had changed, and the CRT functions where different.
There were a handful of breaking changes between VC6, VS2003, VS2005 and VS2008. Visual C++ (in VS2005) stopped support for single-threaded, statically linked CRT library. Some breaking changes enumerated here and here. Those changes will impact your use of VC6 built libs in later versions.

Strange VB6 build problems (related to nlog)

This I think is related to my use of the nlog C++ API (and my question on the nlog forum is here); the purpose of my asking this question here is to get a wider audience to my problem and perhaps to also get some more general ideas behind the VB6 IDE's failure to build in my particular scenario.
Briefly, the problem that I am having is that I am having trouble building VB6 components which reference unmanaged C++ components which have calls to nlog's C\C++ API (which is defined in NLogC.DLL). The build problems are not occurring during compile time, they are occurring when the binary is being built which suggests to me that it's some kind of linker type problem? Don't know enough about how VB6 binaries are produced to tell. The VB6 binary is produced, but it is corrupted and crashes shortly after it is invoked.
Has anyone had any similar experiences with VB6 (doesn't have to be related to nlog or C++)?
edit: Thanks for all the responses to this rather obscure problem. Still no headway unfortunately; my findings since I posted this:
'Tweaking' the compile options doesn't appear to help in this problem.
Adding a reference to the nlog-enabled C++ component from a 'blank' VB6 project doesn't crash it or cause weird build problems. So it isn't a 'native' VB6 issue, possibly an issue with the interaction between nlog and the various components and 3rd party libraries used by other referenced components?
As for C++ calling conventions: the nlog-enabled C++ component is - as far as I can see - compliant to these conventions and indeed works fine when referenced by VB6 as long as it is not making any nlog API calls. Not sure if the nlogc.DLL itself is VB6 compliant but I would have thought that that is immaterial since the API calls are being made from the C++ component; VB6 shouldn't know or care about what the C++ component is referencing (that's as far as my understanding on this goes...)
edit2: I should also note that the error message obtained during build is: "Errors during load. Please refer to "xxx" for details". When I bring up the log file, all that there is in there is: "Cannot load control xxx". Interestingly, all references to that particular control disappears from that particular project resulting in compile errors if I were to try to build again.
Got around the problem by using NLog's COM interface (NLog.ComInterop.DLL) from my unmanaged C++ code. Not as easy to do as the C\C++ API but at least it doesn't crash my VB6 components.
I would try tweaking some of the Compile options found in the Project, Properties menu, Compile panel to see if they yield any additional hints as to what is going wrong.
For example if you compile the executable to p-code rather than native code does it still crash on startup.
What error message do you get when you run your compiled binary?
I doubt the compiler/linker is the problem: project references in a VB6 project are not linked into the final executable. A project reference in VB6 is actually a reference to a COM type library (which may or may not be embedded in a .dll or other binary file type). Project references primarily serve two purposes:
The IDE extracts type information from the referenced type libraries which it then displays in the Object Browser (and in the Intellisense drop-down)
At compile-time, the compiler extracts the type information stored in the referenced libraries, including the CLSID of each class that you instantiate, and embeds this data into the executable. This allows your executable to create instances of classes contained in the libraries that you referenced.
Note that the compiled binary doesn't link to any code in the referenced libraries, and it doesn't even contain the filenames of the referenced libraries. The final executable only contains the CLSID's and other type information that it needs to instantiate COM objects at run-time.
It is much more likely that the issue is with NLog, or with how you are calling it from your code, rather than something gone awry in the VB6 compile process.
If you think it might be a linker problem, this should crash it the same way:
create a new standard project (of any kind)
add a new module and copy the "declare"-statements into it
compile
If it doesn't crash it is something else.
It would help an exact description of the error or a screenshot of what going on.
One thing to check is wherever NLogC.DLL or the C++ DLL you built have the correct calling convention defined. Basically you can't have the DLL function names mangled or use anything but the STDCALL calling convention. If the C++ DLL has not been created with those two things in mind then it will fail to work with VB6.
MSDN Article on Calling convention.
"Cannot load control xxx" errors can be caused by .oca files which were created from a different version of an .ocx than currently used. If that is the case, deleting the .oca files helps.

Resources