.netCoders Contact Us
Search:

Accessing Unmanaged Code

Unmanaged code refers to code that is not run in the Common Language Runtime. This includes two types of code: COM Components and non-COM Components, such as the Win32 API. Depending on the component type containing the method you want to invoke, the process is different, so let's look what's involved with each type.

Invoking COM Components

From a .NET application, you can make use of unmanaged code such as COM components. Using Visual Studio.NET, you first have to add a reference to the COM Component by selecingProject->Add Reference and selecting the COM tab. Behind the scenes, Visual Studio.NET is using the command line type library import utility (tlbimp.exe) to create a managed wrapper around the component. If you expand the References of the web application in Solution Explorer, you will see the name of the reference for the COM component. Then, to use your component, you just instantiate it like any other .NET component.
object myObj = new DotnetCoders.VBComponent();
You should be familiar with the command-line utilities involved with COM Interoperability.

Assembly Registration Utility (RegAsm.exe)
The Assembly Registration Utility is used to register a .NET assembly as a COM callable component. This involves generating a GUID for the component and writing the appropriate registry entries.

TlbImp.exe
The Type Library to Assembly Converter (tlbimp.exe) utility creates an assembly from a COM component, allowing managed code to call the COM component.

TlbExp.exe
The Assembly to Type Library Converter (tlbexp.exe) utility generates a COM type library from a .NET assembly, allowing .NET components to be called by COM components. Note that this utility only generates a type library; it does not register the component. To both generate a type library, and register the component, use the RegAsm.exe utility.

Invoking API Methods

.NET's interoperability features do not stop with COM-based DLLs. Using the Platform Invoke Services (P/Invoke), you can call APIs that are not COM based, such as the Win32 API. The syntax for this varies in C# and VB.NET, so let's look at each language.

VB.NET
The syntax in VB.NET is similiar to that in Visual Basic 6. To use an API function, you have to declare it prior to invoking it, using the following syntax:

Declare StringConversionType (Function | Sub) MethodName Lib "DllName" ([Args]) As ReturnType
The important pieces to note are the StringConversionType, which can be Ansi, Unicode, or Auto, and that the DllName is indicated using Lib "DllName". Also, if the method name in the DLL is different than how you are declaring it, then you must specify the entry point. In VB.NET, you do this with the Alias keyword. Here is an example that declares the Win32 API MessageBox method in the User32.dll. Notice that since we want to use the function as MsgBox, we have to use the Alias keyword and the real name of the function.
Declare Auto Function MsgBox Lib "User32.dll" Alias "MessageBox" _
(hWnd As Integer, txt As String, caption As String, Typ As Integer) As Integer
You can then invoke this method like it were a native .NET method, and the Common Language Runtime will handle the marshaling of the data.

C#
Unlike VB.NET, C# uses attributes to declare an API function. In particular, the DllImport attribute is used, along with the extern keyword. Here is the syntax:

[DllImport("DllName", EntryPoint="RealFunctionName")]
static extern ReturnType FunctionName(Arguments);
Whereas VB.NET has the Alias keyword for specifying the entry point in the DLL, C# relies on a property of the DllImport attribute. Here is the same example we looked at with VB.NET, calling the MsgBox Win32 API function, only in C#:
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint="MessageBox")]
public static extern int MsgBox(int hWnd, String text, String caption, uint type);