Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing C# GUI over a C++ dll or C++ exe

Tags:

c++

c#

dll

I have a C++ console Exe which does some progamming. Now i wanted to write a C# GUI which does some of the programming that the C++ exe does. I was thinking of few approaches,

  1. Write the C# GUI with all programming in C++ done from scratch.(I do not want to do this for the amount of rework it entails)
  2. Build a C++ dll which does the programming and have it imported in GUI app.(Now here i have a concern. How do i capture the output of the routines in c++ dll and display it in GUI? Should i return the output as string for every routine that the app calls.? Since i dont know managed c++ iam going to build an unmanaged C++ dll. )
like image 941
excray Avatar asked Jan 14 '11 04:01

excray


2 Answers

Building a C++/CLI dll really isn't that hard. You basically use unmanaged C++ code except that you define a "public ref class" which hosts the functions you want the C# code to see.

What kind of data are you returning? Single numbers, matrices of numbers, complex objects?

UPDATE: Since it has been clarified that the "output" is iostreams, here is a project demonstrating redirection of cout to a .NET application calling the library. Redirecting clog or cerr would just require a handful of additional lines in DllMain patterned after the existing redirect.

The zip file includes VS2010 project files, but the source code should also work in 2005 or 2008.

The iostreams capture functionality is contained in the following code:

// compile this part without /clr
class capturebuf : public std::stringbuf
{
protected:
    virtual int sync()
    {
        // ensure NUL termination
        overflow(0);
        // send to .NET trace listeners
        loghelper(pbase());
        // clear buffer
        str(std::string());
        return __super::sync();
    }
};

BOOL WINAPI DllMain(_In_ HANDLE _HDllHandle, _In_ DWORD _Reason, _In_opt_ LPVOID _Reserved)
{
    static std::streambuf* origbuf;
    static capturebuf* altbuf;
    switch (_Reason)
    {
    case DLL_PROCESS_ATTACH:
        origbuf = std::cout.rdbuf();
        std::cout.rdbuf(altbuf = new capturebuf());
        break;
    case DLL_PROCESS_DETACH:
        std::cout.rdbuf(origbuf);
        delete altbuf;
        break;
    }

    return TRUE;
}

// compile this helper function with /clr
void loghelper(char* msg) { Trace::Write(gcnew System::String(msg)); }
like image 199
Ben Voigt Avatar answered Oct 13 '22 12:10

Ben Voigt


So you just want to call c++ library from managed .net code?

Then you would need to either build a COM object or a p-invokable library in c++. Each approach has it's own pros and cons depending on your business need. You would have to marshall data in your consumer. There are tons and tons of material on both concepts.

like image 45
dexter Avatar answered Oct 13 '22 12:10

dexter