zondag 27 november 2011

Constructing a managed dll

Integrating tetgen with Unity poses one big problem: Tetgen is written in C++ and Unity only understands C# (And boo and javascript, but that's besides the point..).
In order for our C# code to use the Tetgen library, we'll have to construct something called a managed .dll file from out c++ code.
Today, I've been experimenting with how this works and I've managed to write a simple class in C++ and integrate it into a C# project.
I searched the internet far and wide for a decent example and this tutorial eventually proved to be the most useful.

Here's the gist of it:

The point: We want a manpaged .dll file. This is a dynamically linked library in assembly that is written in a format that is readable by the .NET framework (CLR). Once we have that, we can just include the .dll file in our C# project and use it as if it was written in C#.

But how? First of we want to compile our C++ code into a static library. I did this using Visual C++ 2010. Set up a new Win32 console application and pick 'static library' from the wizard menu that pops up. Be sure to unselect precompiled header. Now just create the class(es) you would like to use. It's best to put them in a some sort of namespace.
Next we want to create a wrapper class for our C++ class. This wrapper class will be written in C++/CLI (an extension to C++ that is used just for this purpose). The wrapper class will use our static library and be compiled into the managed dll file we want. In visual c++ 2010 we do this by creating an empty CLR project and letting it reference our static library (you can do this by adding the name of the lib in project properties->linker->input->additional dependencies and by adding the directory of the .lib file in project properties->VCC directories->lib directories and the directory of the header files in project properties->VCC directories->include directories)
Next we add a managed class (managed datatypes are datatypes that are understood by the .NET framework, which is what we want) that has a pointer to our C++ class referenced by our library (It's important this is a pointer because the C++ class uses the native heap and a managed data type can have no notion of the native heap). We'll also have to make sure we replace the native datatypes (such as string) by managed datatypes. For example, a double maps to System::Double.
Some code goes a long way to clarify this:

#pragma once

#include
using namespace MathLib;

namespace MathWrapper
{

public ref class ManagedMath
{
private:

MyMathLib* lib;

public:
ManagedMath(void);
~ManagedMath(void);

double add(double a, double b);
};
}

Note the 'public' before the reference class. This is important as it was the source of a heap of trouble for me.

Now what? Now we compile the above code (+the actual cpp file with the implementation) into a dll (project properties->configuration type->Dynamically linked library). Now all that remains is adding this dll to your C# project and adding the correct 'using' statement.

Oh, and I apologize for the gazillion typos in this post, I have a bus to catch.
Next posts: More literature and the result of trying this method on the actual tetgen!

Cheers

Geen opmerkingen:

Een reactie posten