Using Unmanaged DLLs in C#

Started by
0 comments, last by Moeller 14 years, 4 months ago
Hello, everyone. I will try to make this question as specific as possible. I am trying to write a vector library in Visual Studio 2008 as an exercise. My hope is to make use of the SSE instructions for operating on packed single-precision floating point values. While it is rather trivial to get the inline assembly to work in native C, I am having trouble getting it to work in C#, which expects managed code. I am trying to work around this problem by creating a DLL in Managed C++ and using the DLLImportAttribute to load the resulting DLL so I can call my routines that use native assembly. The problem is that as soon as I call any routine, CLR throws a BadImageFormatException right on the spot. Here is the source code (Written in Managed Visual C++) that I made for the DLL file:

// This is the main DLL file.

#include "stdafx.h"

#include "VectorDLL.h"

struct vector_f
{
	float x,y,z,w;
};

vector_f __add(vector_f a, vector_f b)
{
	vector_f t;
	__asm
	{
		movups xmm0, a
		movups xmm1, b
		addps xmm0, xmm1
		movups t, xmm0
	}
	return t;
}

Here is the C# code where I call the routine exposed by the DLL:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Vector
{
    public struct vec
    {
        private float x, y, z, w;

        public vec(float x, float y, float z)
        {
            this.x = x; this.y = y; this.z = z; this.w = 1.0f;
        }

        public vec(float x, float y, float z, float w)
        {
            this.x = x; this.y = y; this.z = z; this.w = w;
        }
    }


    class Vector
    {
        private vec t;

        [DllImportAttribute("VectorDLL.dll")] static extern vec __add(vec a, vec b);

        public Vector(float x, float y, float z)
        {
            this.t = new vec(x, y, z);
        }
        public Vector(float x, float y, float z, float w)
        {
            this.t = new vec(x, y, z, w);
        }

        public Vector(vec s)
        {
            this.t = s;
        }
        
        public static Vector operator +(Vector a, Vector b)
        {
            // Exception thrown here: BadImageFormatException (HRESULT 0x8007000B)
            return new Vector(__add(a.t, b.t));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Vector a = new Vector(1, 2, 3);
            Vector b = new Vector(4, 5, 6);

            try
            {
                Vector c = a + b;
            }
            catch (DllNotFoundException e)
            {
                MessageBox.Show(e.Message);
                return;
            }
            catch (EntryPointNotFoundException e)
            {
                MessageBox.Show(e.Message);
                return;
            }
            Console.ReadLine();
        }
    }
}

Thanks for your help.
Advertisement
The DllImport is for native dlls, while Managed C++ creates managed .NET dlls which you can use directly in C#. Beside this Managed C++ is already deprecated and replaced by C++/CLI.

In general you have to be carefull about performance when going to the unmanaged world just for a few SSE instructions, because the overhead can be pretty high. Maybe take a look at SlimGen as well which tries to solve the same problem.




This topic is closed to new replies.

Advertisement