1

This is the situation. I am writing a backend application in C++ and my colleagues are using C# for the frontend. Basically, my backend application does image processing on images received from the C# frontend and returns a text file with data about the image. What we were doing earlier was writing the images to disk and calling the C++ application with the file path of the image as a parameter. However, this writing/reading from disk has become a bottleneck, so we are wanting to convert the C++ application to a DLL.

At the basic level, what I want is to expose a single method from my C++ application to the C# one through a DLL (the C# application is web-based):

int ProcessImage(System::Bitmap^ image, System::String ^results)

How can I go about doing this? I am using VC++ Express 2008 and my C++ code currently compiles with CLR (although I have mixed a lot of native C++ code inside).

I have been looking around on the web, but am still stuck on how to do this. I think a C++/CLI DLL is the best option, but how do I do this? Writing a DLL in C/C++ for .Net interoperability

Community
  • 1
  • 1
Amil
  • 503
  • 1
  • 5
  • 13
  • 1
    possible duplicate of [C++/CLI Mixed Mode DLL Creation](http://stackoverflow.com/questions/2691325/c-cli-mixed-mode-dll-creation) – Hans Passant Mar 23 '12 at 00:15

2 Answers2

2

If you label your C++ function as a "C" function, then it can be called by PInvoke.

Your C function will look like this:

extern "C" __declspec(dllexport) int Test() {
    return 1;
}

Your C# reference will be like this:

[DllImport("test.dll")]
public static extern int Test();

If you C++ function is an instance member, then you can still do it but it requires some tricks.

Nick Whaley
  • 2,729
  • 2
  • 21
  • 28
  • 2
    You should also add __stdcall to the C++ function, or CallingConvention to the DllImport – Joel Lucsy Mar 23 '12 at 01:29
  • 1
    I believe that extern "C" prevents function/method name mangling. – 01100110 Mar 23 '12 at 02:37
  • Only functions in the global namespace can be exported in a way that's compatible with p/invoke. Forget about anything having to do with classes, whether you mean member functions of classes (static or not) or class types in parameters or return values. – Ben Voigt Mar 23 '12 at 02:58
  • Thanks for the response, but I don't think this will work with what I am trying to do. How can I use this method to pass the image by reference and receive results as a string? – Amil Mar 23 '12 at 05:47
1

I finally figured it out. What you need to do is:

  1. In your C++ project, set the option in Visual C++ to compile with clr pure, which makes the project a C++/CLI one
  2. In your C++ project, expose methods by creating a public ref class:

    public ref class Interop
    {
    public:
        //! Returns the version of this DLL
        static System::String^ GetVersion() {
            return "3.0.0.0";
        }
    
        //! Processes an image (passed by reference)
        System::Int32^ Process(Bitmap^ image);
    }
    
  3. In a C# program, add a reference to the C++ DLL you compiled
  4. In the C# program, call these methods (i.e. Interop::Process(myBitmapInCS))

I believe this method is called "implicit P/Invoke" Hope this helps!

Amil
  • 503
  • 1
  • 5
  • 13