user613326
user613326

Reputation: 2180

using c++11 inside a c# program

I am programming some graphical filters in my main program which is based upon C#.
However C# is not fast for getpixel / putpixel.
I've seen workarounds for it, using unsafe code in C#
Unsafe code gives me a bit an unsafe feeling too, as i understand the benefit of safe code and memory cleanup.

So now i am wondering....
Might it be better to write this unsafe code in a separated dll based on C++ ?.
However I never made mixed language programs, so i am wondered.

Also what if i used another compiler to write the c++11 .dll would that be a problem? The main program is written in visual studio 2010 expres

Upvotes: 1

Views: 300

Answers (4)

Maku
Maku

Reputation: 1558

Actually I am doing exactly the same you mentioned (graphical filters) using CUDA. To be able to call C functions from managed code (WinForms) I utilize InteropServices.

Let's say you have 2 projects in a solution - C++ library and some C# project.

To declare function in C++ library I use following parameters:

extern "C" int __declspec(dllexport) __stdcall cudaCopyInputData
    (int n, int w, int h, byte* data)
{
    inputBuffer = data;
    bufferLength = n;
    inputWidth = w;
    inputHeight = h;
    useFloatBuffer = 0;
    binaryBufferValid = 0;

    int bufferSize = bufferLength * sizeof(byte);
    int floatBufferSize = bufferLength * sizeof(float);
    int binaryBufferSize = w * h * sizeof(int);

    cudaMalloc((void**)&cudaInputBuffer, bufferSize);
    cudaMemcpy(cudaInputBuffer, inputBuffer, bufferSize, cudaMemcpyHostToDevice);

    cudaMalloc((void**)&cudaFloatBuffer, floatBufferSize);
    cudaMalloc((void**)&cudaBinaryBuffer, binaryBufferSize);

    return 0;
}

To be able to use it from C# project I import this function as a static method using InteropServices:

[DllImport("CUDA Dll.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        public static extern int cudaCopyInputData(int n, int w, int h, IntPtr data);

You are then able to use it from managed code as a standard method.

To pass Bitmap data to the imported method you can use something like this:

BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);

Then pass bmpData.Scan0 as a pointer to bitmap data and some other parameters like Width, Height, Stride or whatever you want to figure out data format in the C function. In the example above you will have 4 bytes for every pixel (3 bytes + 1 dummy byte) so it's comfortable to process it.

To reuse processed data from your bmp object you just call after processing it:

bmp.UnlockBits(bmpData);

Upvotes: 4

Felix K.
Felix K.

Reputation: 6281

If you use C++ then you also can use C# with unsafe code. Both is unsafe and in C# you still don't need to care about memory cleanup. The only thing you have to care about is accessing invalid pointers which will cause a AccessViolationException.

public unsafe void SwapChannels(Byte[] imageSrc)
{
    fixed (Byte* pImageSrc = imageSrc)
    {
        // Swap channels here
    }
}

I'm using unsafe code in my image libraries too. If you are not going cross-plattform you can also use C++/CLI.

Upvotes: 1

user1610015
user1610015

Reputation: 6678

There are a few ways to do interop between C++ and C#: C++/CLI, COM and P/Invoke.

C++/CLI and COM have areas in which either one can be better, but I don't think P/Invoke should ever be used, except for some quick-and-dirty solutions.

In your case, especially since you mention that the C++ DLL is built with another compiler, I think COM is your best bet.

But note that using C++ is pretty much like using unsafe code in C#. Pointers all around, for example.

Upvotes: 1

user18428
user18428

Reputation: 1201

SWIG allows you to easily wrap C++ code and expose classes/functions in c#. I used it to expose some of my image processing routines in c# and it's a breeze.You end up with classes behaving as c# classes , the SWIG generated wrappers handle the type conversions (mostly) and the P/Invoke stuff.

The site swig.org is down at the moment i'm writing, if somebody knows why ,please comment

As for the compiler mixup I have good experience with Mingw compiled DLL.

edit: You still can access the project sourceforge page

Upvotes: 0

Related Questions