The output for interop logging consists of the signatures of the interop function calls as they occur at run time, with any error messages.
The .NET Compact Framework version 3.5 includes enhanced interop logging support, which is described in the "Deep Marshaling" section later in this topic.
The signatures for both managed-to-native and native-to-managed calls are logged, and include the following types of calls:
Interop logging can help you troubleshoot problems when you call or return from an interop function call, such as when an incorrect parameter type is marshaled or when the program terminates unexpectedly.
The output for a function signature entry consists of three lines for each interop call. The first line provides flags that identify the type of function call made, and includes one or more of the following elements:
- [pinvokeimpl]
Identifies a managed-to-native call that uses the DllImportAttribute attribute.
- [Ctor]
Identifies a constructor for an interop assembly class, generated by the Type Library Importer (Tlbimp.exe).
- [preservesig]
Assumes that the managed and native functions have the same signature, with no translation from HRESULT to exception enforced by the runtime.
- [delegate]
Indicates that the function is a native-to-managed delegate callback. The delegate acts as a function pointer in native code.
The second line of the interop log file represents the managed signature. For managed-to-native function calls, this line identifies the managed function that calls the native code. For native-to-managed function calls, this line identifies the managed function that is being called from native code.
The third line represents the native signature, as expected by the runtime. This line identifies data types for each parameter and provides information about how the managed object data is marshaled. The runtime assumes that the correct types are specified by the DllImportAttribute attribute or in the COM interface signature definition. Failure to specify the correct types is a common error that can cause unexpected behavior, because the function will be executed with incorrect parameter values.
Note: |
|---|
Specifying an incorrect parameter type may result in a NotSupportedException or a native exception. To help isolate the failure, change parameter types to known supported types or to an IntPtr. |
Every type has a default marshaling type. Note that the marshaling behavior of a managed type can be different for COM calls and DllImportAttribute or delegate callback calls. You can use the MarshalAsAttribute attribute to specify a marshaling type other than the default. You must also use the ref keyword to identify any parameter that represents a pointer to a value type or a pointer to a pointer, for a reference type.
The following table shows interop logging of a platform invoke.
Line number and description | Log entry |
|---|
1 - Type of function call | [pinvokeimpl][preservesig] |
2 - Managed signature | bool PlatformDetector::SystemParametersInfo(uint , uint , System.Text.StringBuilder , uint ); |
3 - Native signature | BOOLEAN (I1_WINBOOL_VAL) SystemParametersInfo(unsigned int (U4_VAL) , unsigned int (U4_VAL) , WCHAR * (STRINGBUILDER_LPWSTR) , unsigned int (U4_VAL) ); |
The following table shows interop logging of a delegate callback.
Line number and description | Log entry |
|---|
1 - Type of function call | [preservesig][delegate] |
2 - Managed signature | int WndProc::Invoke(WndProc , IntPtr , uint , uint , int ); |
3 - Native signature | int (I4_VAL) (*)(INT_PTR (I_VAL) , unsigned int (U4_VAL) , unsigned int (U4_VAL) , int (I4_VAL) ) |
The following table shows interop logging of a native-to-managed COM function call, where the runtime returns a failure HRESULT if a managed exception occurs.
Line number and description | Log entry |
|---|
1 - Type of function call | (no flags) |
2 - Managed signature | int N2MDualComponentImp.IN2MDualInterface::GetInt(N2MDualComponentImp.IN2MDualInterface This); |
3 - Native signature | HRESULT GetInt(IN2MDualInterface *(INTF_VAL) this, [retval] int (I4_VAL) retval); |
The .NET Compact Framework version 3.5 also supports deep marshaling for interop logging. In deep marshaling, information is logged about marshaled objects that are contained in structures or in reference types.
The following log output shows an example of a platform invoke call that uses marshaled objects contained in a structure. The first line of the deep marshaling section specifies why the deep marshaler was called. In this example, it was called to compute the size of the structure. The log shows the data type and the size, in bytes, of each object. The index values (for example, 0004) represent the byte offsets for the specified variables.
DEEP MARSHAL: Get size
struct interoplogging.MyStruct
{
0000: Int32 myVar as Int32 (4 bytes)
0004: Int32 myVar2 as Int32 (4 bytes)
0008: String myString as WCHAR[10] (20 bytes)
}
DEEP MARSHAL: Total size = 28 bytes
[pinvokeimpl][preservesig]
void interoplogging.Form1::MyAPI(interoplogging.MyStruct );
void MyAPI(MyStruct (NONBLIT_VALUETYPE_VAL) );
DEEP MARSHAL: Managed -> Native
struct interoplogging.MyStruct
{
0000: Int32 myVar as Int32 (4 bytes)
0004: Int32 myVar2 as Int32 (4 bytes)
0008: String myString as WCHAR[10] (20 bytes)
}
DEEP MARSHAL: Total size = 28 bytes
There are differences between the .NET Compact Framework implementation of COM interoperability and that of the full .NET Framework. The .NET Compact Framework does not support the following:
Creating a CCW that contains an interface without a specified GUID.
Creating an RCW for a class that inherits from an interop assembly class.
Creating a CCW that contains a nongeneric interface with a generic method.
RCWs are usually cleaned up upon finalization, but you can also use the ReleaseComObject or FinalReleaseComObject method to release the RCW that is associated with an object. If you are using these advanced options to manage the lifetime of your objects and you try to use the object after it has been freed to make a native COM call, an exception is thrown and the log file contains an error message about the cause of the exception.