My Development Notes

By Haemoglobin
3/10/2010 (revision 1)

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

BestFitMappingAttempts 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.
CallingConventionThe calling convention to use when passing method arguments. WinAPI typically sufficient.
CharSetControls how string params marshaled. Default is CharSet.Ansi, or use CharSet.Unicode.
EntryPointSpecifies the name of the function to be called if different from the method name.
ExactSpellingControls whether CharSet property causes other entry point names to be searched for.
PreserveSigDefault is true which directly translates the return values (HRESULT/retval). If set to false exceptions are raised instead.
SetLastErrorDefaults to false in C# (true in VB - adds overhead), if true enables the caller to use Marshal.GetLastWin32Error()
ThrowOnUnmappableCharIf 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) {}
AutomationProxyAttributeSpecifies whether types should be marshaled using Automation marshaler or custom proxy.
ClassInterfaceAttributeControls whether Tlbexp.exe automatically generates a class interface. ClassInterfaceAttribute.None is recommended (for versioning) and define your own interfaces to exposed classes.
Com[Un]RegisterFunctionAttributeSpecifies the method to run when a the assembly is registered/unregistered for COM.
ComSourceInterfacesAttributeIdentifies COM event sources.
ComVisibleAttributeSet to false to hide, defaults to true.
InAttributeData should be marshaled into the caller.
OutAttributeData must be marshaled from a called object back to its caller. Equivalent to the out keyword.
ProgIdAttributeSpecifies the ProgID of a class manually. Otherwise autogenerated by combining namespace with type name.

Comments

Powered by BlogEngine.NET 1.6.1.0 | Design by styleshout | Enhanced by GravityCube.net | 1.4.5 Changes by zembian.com | Adapted by HamishGraham.NET
(c) 2010 Hamish Graham. Banner Image (c) Chris Gin