Marshaling Overview
The .NET Compact Framework version 2.0 provides expanded marshaling support through IDispatch and through platform invoke and vtable calls. This support includes the following:
Using the MarshalAsAttribute attribute.
Marshaling variant types supported on Windows CE.
Marshaling types that call COM interfaces through a vtable.
Marshaling structures with embedded arrays and strings.
Specifying the layout for a structure.
Marshaling types greater than 32 bits passed by value, including structures.
You can marshal the following types either by value or by reference:
BStr
IUnknown
IDispatch
SafeArray
DateTime (marshaled as an OLE DATE)
Variant
Note that the .NET Compact Framework version 2.0 supports the AllocHGlobal and FreeHGlobal methods.
Interop Logging
You can create log files of the function signatures to see how an interop call is marshaled. For information about creating the files, see How to: Create Log Files. For information on how to interpret the log files, see Log File Information.
Marshaling Differences with the full .NET Framework
The .NET Compact Framework does not support the following marshaling and interoperability features in the full .NET Framework:
Custom Marshaling
Obtaining a managed delegate from a native function pointer using the GetDelegateForFunctionPointer method. You can, however, create a native function pointer from a managed delegate.
Accessing .NET Compact Framework classes from native components.
Return type for a vtable or platform invoke function
Passing structures (VT_RECORD) through IDispatch.
Passing Int64 and UInt64 types through IDispatch.
The .NET Compact Framework has differences in the following marshaling behaviors:
The .NET Compact Framework allows arrays of SCODE values to be marshaled, but the full .NET Framework does not.
The .NET Compact Framework marshals arrays of IUnknown and IDispatch pointers differently than the full .NET Framework.
The .NET Compact Framework initializes all threads as multi-threaded apartments and does not support other threading models or setting an apartment model. Consequently, the .NET Compact Framework does not support the ApartmentState and the following methods and attributes:
Marshaling with the Visual Basic Declare Statement
The Visual Basic Declare statement is an alternative to declare references to external procedures in a DLL. Note that Ansi keyword in the Declare statement is not supported.
Marshaling is identical between the Declare statement and the DllImportAttribute, except for ByVal String objects. In a Declare statement, a ByVal String parameter will be marshaled as an out parameter. Since strings are immutable, this forces the common language runtime to copy the string and return a new reference.
Differences Between IDispatch and Platform Invoke Marshalers
The following table lists the types that are marshaled differently by the two marshalers.
Type | IDispatch | Platform invoke and vtable |
---|---|---|
BStr |
wchar * |
|
Variant |
NULL |
|
VARIANT_BOOL |
byte |
|
SafeArray |
C-style array |
The .NET Compact Framework marshals a class through platform invoke without the StructLayoutAttribute as an auto-layout structure; the full .NET Framework marshals it as a CCW (COM callable wrapper).
Note that the .NET Compact Framework marks a SafeArray with FADF_FIXEDSIZE and throws an exception if you resize it in native code.
Marshaling Delegates
By default, delegates are marshaled as function pointers. You can also explicitly use the FunctionPtr value from the UnmanagedType enumeration for creating an instance of the MarshalAsAttribute. See Marshaling Delegates as Function Pointers for examples.
Specifying a Character Set
You can use the CharSet field of the DllImportAttribute to specify a character set when marshaling strings through platform invoke.
The .NET Compact Framework supports the following two values:
Auto. This is the default. Strings are marshaled using the Unicode character set.
Unicode. Strings are marshaled using the Unicode character set.
The value Ansi is not supported because Windows CE is Unicode only. None is equivalent to Ansi and is not supported.
Because the .NET Compact Framework does not support the ExactSpelling field, the common language runtime automatically searches for an entry point according to the values specified by CharSet.
Object Pinning
When the .NET Compact Framework common language runtime marshals an object, the object is pinned for the duration of the platform invoke call to ensure that the garbage collector does not free or move the object.
Memory Usage
Use the following guidelines for handling memory with unmanaged code in the .NET Compact Framework:
Always allocate memory in managed code and pass it to unmanaged code.
If unmanaged code holds a pointer to a managed component, you must manually pin the object using the GCHandle structure.
The .NET Compact Framework common language runtime coinitializes threads at startup and couninitializes them on shutdown. Threads are marked as "free threading."