tags:

views:

309

answers:

1

We have a mixed mode assembly that contains both VC++ (using MFC) and C++/CLI classes. It is an MFC Extension dll and is loaded into our MFC executable at runtime and all works well.

When we come to unit test the unmanaged classes in there from another C++/CLI assembly, we see the following exception everytime we try to create an instance (via new) of an unmanaged class:

Exception
System.TypeInitializationException: The type initializer for '<Module>' threw an exception. ---> <CrtImplementationDetails>.ModuleLoadExceptionHandlerException: A nested exception occurred after the primary exception that caused the C++ module to fail to load.
 ---> System.Runtime.Serialization.SerializationException: Serialization error.
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr function, Void* cookie)
   at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr , Void* )
   at <CrtImplementationDetails>.LanguageSupport.InitializeDefaultAppDomain(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 518
   at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 721
   at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 875
   --- End of inner exception stack trace ---
   at <CrtImplementationDetails>.ThrowNestedModuleLoadException(Exception innerException, Exception nestedException)
   at <CrtImplementationDetails>.ThrowNestedModuleLoadException(Exception , Exception )
   at <CrtImplementationDetails>.LanguageSupport.Cleanup(LanguageSupport* , Exception innerException) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 841
   at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* ) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 883
   at .cctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 922
   --- End of inner exception stack trace ---
   at MSMContactDataTests.LoadUnknownItemTest()

This looks like a failure to load the assembly by the test runner (Gallio.Echo in this case).

I have also created a small C++/CLI console app and tried effectively the same thing. I can correctly create an instance of a ref class contained in the assembly, but when I try to new up an unmanged class, I get the same exception.

Any ideas?

EDIT

I was going to post the console app code that broke here, but I have recompiled it and it now works! Here it is:

#include "stdafx.h"

using namespace System;

#include "SCacheAssignment.h"

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");
    SCacheAssignment* assignment = new SCacheAssignment(NULL, false);
    assignment->id = 2;
    Console::WriteLine(L"Hello World 2 " + assignment->id);
    return 0;
}

When I use his code is a unit test:

#include "stdafx.h"

#include "PBSMSDataStoreUnitTests2.h"
#include "SCacheAssignment.h"

using namespace PBSMSDataStoreUnitTests2;

void Class1::SomeTest()
{
    Console::WriteLine(L"Hello World");
    SCacheAssignment* assignment = new SCacheAssignment(NULL, false);
    assignment->id = 2;
    Console::WriteLine(L"Hello World 2 " + assignment->id);
}

It breaks. This is the only test in the test assembly.

The console app is a CLR Console Application where the test assembly in an CLR Class Library. As far as I can tell, they use the same compiler options. Why does one work and one not?

+1  A: 

Is your unit test assembly also C++/CLI?

(edited based on new information)

Intriguing. I wonder if it could be due to a managed static constructor failing in the mixed-mode DLL? Or something going awry in constructing a global native variable?

I found mention of the same problem in this Connect issue: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=316549

but no solution or proper diagnosis, I'm afraid.

Kim Gräsman
Yes, the test assembly is also in C++/CLI. I'll edit the post to include the test console app code that breaks.
Colin Desmond
An interesting link. Thank you.
Colin Desmond
Colin, do you have any global constructors in your DLL?
Kim Gräsman
What do you mean by "Global Constructors"?
Colin Desmond
Sorry, not very clear. I mean any objects that are constructed on module load. That includes global or static native objects and static constructors on managed types.
Kim Gräsman