COM Interop
- Simply add reference to COM dll in add references dialog
- If need to use a type in a COM library, use "tlbimp comassembly.dll" generates a .NET assembly with the type.
- Win32 functions return false if an error occured, then use Marshal.GetLastWin32Error() to get the error code
Or
[DllImport("user32.dll"[, EntryPoint])]
private static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
MessageBox(new IntPtr(0), "Hello World", "My popup", 0);
//Callback required
public delegate bool CallBack(int hwnd, int lParam);
[DllImport("user32"]
public static extern int EnumWindows(CallBack x, int y);
EnumWindows(new CallBack(Report), 0);
public static bool Report(int hwnd, int lParam) {
...
return true;
}
DllImport Parameters
| BestFitMapping | Attempts to find a similar character when mapping from Unicode to ANSI when no exact match exists. For example the unicode © symbol to the ANSI "c", otherwise "?" if no map exists and exception thrown if ThrowOnUnmappableChar is true. |
| CallingConvention | The calling convention to use when passing method arguments. WinAPI typically sufficient. |
| CharSet | Controls how string params marshaled. Default is CharSet.Ansi, or use CharSet.Unicode. |
| EntryPoint | Specifies the name of the function to be called if different from the method name. |
| ExactSpelling | Controls whether CharSet property causes other entry point names to be searched for. |
| PreserveSig | Default is true which directly translates the return values (HRESULT/retval). If set to false exceptions are raised instead. |
| SetLastError | Defaults to false in C# (true in VB - adds overhead), if true enables the caller to use Marshal.GetLastWin32Error() |
| ThrowOnUnmappableChar | If set to true exception is raised if an ummapable character is encountered (i.e ?). |
Exposing .NET types to COM
- All methods, properties, fields etc must be public.
- Put [ComVisible(false)] above members to be hidden from COM
- Default constructor with no parameters
- No abstract types
- Avoid static methods
- Include ApplicationException.HRESULT error codes in custom exception classes (.NET exceptions i.e IOExecption automatically map to appropriate HRESULT i.e COR_E_IO HRESULT)
- "tlbexp NETAssembly.dll" to generate a COM assembly.
- Or register the assembly for COM either through VS.NET (tick Register For COM Interop) in Output section, or
use regasm NETAssembly.dll
Using non-default marshaling:
[return: MarshalAs(UnmanagedType.LPWStr)]
public string MyMethod(MarshalAs([UnmanagedType.LPWStr)] string myString) {}
| AutomationProxyAttribute | Specifies whether types should be marshaled using Automation marshaler or custom proxy. |
| ClassInterfaceAttribute | Controls whether Tlbexp.exe automatically generates a class interface. ClassInterfaceAttribute.None is recommended (for versioning) and define your own interfaces to exposed classes. |
| Com[Un]RegisterFunctionAttribute | Specifies the method to run when a the assembly is registered/unregistered for COM. |
| ComSourceInterfacesAttribute | Identifies COM event sources. |
| ComVisibleAttribute | Set to false to hide, defaults to true. |
| InAttribute | Data should be marshaled into the caller. |
| OutAttribute | Data must be marshaled from a called object back to its caller. Equivalent to the out keyword. |
| ProgIdAttribute | Specifies the ProgID of a class manually. Otherwise autogenerated by combining namespace with type name. |