Categories
Code Snippets Hints/Tips

Calling C Library DLLs from C#

In order to utilize legacy software, you may require a technique for calling unmanaged code written in C from C#.

Here is a simple example that shows how this can be achieved.

Create a simple DLL (lib1.dll)

#include <stdio.h>
#include <stdlib.h>

extern "C"
{
// simple print
	__declspec(dllexport) void __stdcall PrintFromDLL()
	{
		printf ("printing from the DLL\n");
	}
// access an array
	__declspec(dllexport) void __stdcall OneDArray(int n, double anArray[])
	{
		int i;
		for (i=0; i<n; i++)
		anArray[i] = i;
	}
}

The DLL contains 2 functions: a simple function to print to the console window, and a function used to initialise an array.

extern “C” is used to declare that the functions have external linkage i.e. they are visible from other files and have a “C” calling convention with unmangled names. If omitted, the function name is exposed as a C++ function with a mangled name.

The declaration __declspec(dllexport) is necessary to indicate functions which are available externally from the dll.

Create a C# Test Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Runtime.InteropServices;

namespace testcall1
{
    class Program
    {
        [DllImport("lib1.dll")]
        public static extern void PrintFromDLL();
        [DllImport("lib1.dll")]
        public static extern void OneDArray(int n, double[] anArray);
        
        public static void CallOneDArray(double[] anArray)
        {
            OneDArray(anArray.GetLength(0), anArray);
        }
        
        static void Main(string[] args)
        {
            Console.WriteLine("This is C# program");
            PrintFromDLL();

            int n = 10;
            double[] anArray = new double[n];
            CallOneDArray(anArray);
            for (int i = 0; i < n; i++)
                Console.WriteLine("{0}", anArray[i]);
        }
    }
}

The System.Runtime.InteropServices namespace provides a collection of classes useful for accessing COM objects, and native APIs from .NET

DllImport is used to tell the compiler to declare a function residing in the lib1.dll

Here is the output from the test program

Other Links

How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005 at
http://support.microsoft.com/kb/828736

A document from the Numerical Algorithms Group (NAG) provides a useful insight

Calling C Library DLLs from C#