Carl said:
First thing I'd check - was the definition of the static variables and the
code that initializes them even included in the DLL? More than likely, the
linker simply left it out, since it's not referenced. In general, you have
to force a reference to something to be guaranteed that it's included in the
linked image.
I have thought of this, but I do not think that this is the problem.
First, I have tried to switch on the "Keep Unreferenced Data
(/OPT:NOREF)" option to the linker and it made no difference. Secondly,
I can see the unreferenced symbol '*halo_unit_test_28' in the IL
disassembly (see below).
***************************************
..field static assembly method void *()
'?A0xfabd948e.halo_unit_test_28$initializer$' at D_00024424
..field static assembly valuetype
halo.unit_test.'test_case<halo::serialization::dotnet::stream_obuffer_test>'
'?A0xfabd948e.halo_unit_test_28' at D_000369BC
..method assembly static void
'?A0xfabd948e.??__E?A0xfabd948e@halo_unit_test_28@@YMXXZ'() cil managed
{
.vtentry 30 : 1
// Code size 36 (0x24)
.maxstack 4
IL_0000: ldsflda valuetype
halo.unit_test.'test_case<halo::serialization::dotnet::stream_obuffer_test>'
'?A0xfabd948e.halo_unit_test_28'
IL_0005: ldsflda valuetype
'<CppImplementationDetails>'.$ArrayType$$$BY0DB@$$CBD
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
'?A0xfabd948e.unnamed-global-2'
IL_000a: ldsflda valuetype
'<CppImplementationDetails>'.$ArrayType$$$BY0DN@$$CBD
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
'?A0xfabd948e.unnamed-global-1'
IL_000f: ldc.i4.s 28
IL_0011: call valuetype
halo.unit_test.'test_case<halo::serialization::dotnet::stream_obuffer_test>'*
modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall)
'halo.unit_test.test_case<halo::serialization::dotnet::stream_obuffer_test>.{ctor}'(valuetype
halo.unit_test.'test_case<halo::serialization::dotnet::stream_obuffer_test>'*
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
modopt([mscorlib]System.Runtime.CompilerServices.IsConst),
int8
modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte)
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)*,
int8
modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte)
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)*,
int32)
IL_0016: pop
IL_0017: ldftn void
'?A0xfabd948e.??__F?A0xfabd948e@halo_unit_test_28@@YMXXZ'()
IL_001d: call int32 _atexit_m(method void *())
IL_0022: pop
IL_0023: ret
} // end of global method
'?A0xfabd948e.??__E?A0xfabd948e@halo_unit_test_28@@YMXXZ'
..method assembly static void
'?A0xfabd948e.??__F?A0xfabd948e@halo_unit_test_28@@YMXXZ'() cil managed
{
.vtentry 29 : 1
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldsflda valuetype
halo.unit_test.'test_case<halo::serialization::dotnet::stream_obuffer_test>'
'?A0xfabd948e.halo_unit_test_28'
IL_0005: call void
modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall)
'halo.unit_test.test_case<halo::serialization::dotnet::stream_obuffer_test>.{dtor}'(valuetype
halo.unit_test.'test_case<halo::serialization::dotnet::stream_obuffer_test>'*
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
modopt([mscorlib]System.Runtime.CompilerServices.IsConst))
IL_000a: ret
} // end of global method
'?A0xfabd948e.??__F?A0xfabd948e@halo_unit_test_28@@YMXXZ'
***************************************
To me it looks as if the compiler has emitted the code that does the
initialization, but for some reason this code is not called when the
class library is loaded. Do CLR defer the initialization until the
symbol is referenced? If so, how do I explicitly trigger this
initialization without referring to the symbol itself?