none
c# GUI and C++ program RRS feed

  • Question

  • How can I use a C# GUI to communicate with a C++ program or C++ code.
    I need to use the GUI to input arguments into the C++ program.

    Thanks.
    Thursday, May 15, 2008 12:13 AM

Answers

  • It's not particularly elegant but it sounds like the most simple way forward for you is to just make a call to the compiled c++ executable with command line parameters specified in the C# gui.

     

    You will need to make a change to your C++ code to accomodate taking in the command line parameters, and in the C# you need to do something like this:

     

    Code Snippet

    ProcessStartInfo myNewProcessStartInfo = new ProcessStartInfo();

    myNewProcessStartInfo.FileName = "name and location of the c++ executable";

    myNewProcessStartInfo.Arguments = "command line parameters to pass the new process";

    Process.Start(myNewProcessStartInfo);

     

     

    Depending on whether you have the opportunity to do so however I would consider making changes to your C++ code to create a dll instead which can be accessed by the C# code directly. It would be a more elegant solution but obviously only you know whether the time taken to make this change is worthwhile or necessary.

     

    I hope this helps - if you need more information please post again.

     

    Best

     

    J

    Thursday, May 15, 2008 9:59 PM
  •  

    Well, if you have the source you can write a wrapper. I have already done this, but i have had a dll. i created a new solution and added a new c# windows executable project and a new c++ CLR project. CLR means common language runtime and it has the /clr tag in compiler options that means it is compatible to c# (.NET). So if you write a wrapper you have to use special syntax and operator, but if you do, you can use your c++ functions in c# GUI as if they would be written in c# itself.

    Watch this little example of a c++ class, which is usable in c# as a normal class with normal properties...

     

    Code Snippet

    using namespace System;

    public ref class PropClass

    {

    private:

    String ^_name;

    String ^_number;

    unsigned char _crc;

    public:

    /*

    Constructor.

    */

    PropClass(String ^name,

    String ^number,

    unsigned char crc)

    {

    _name = name;

    _number = number;

    _crc = crc;

    }

    // Property forward deklaration

    property String ^Name{String ^get();}

    property String ^Number{String ^get();}

    property unsigned char CRC{unsigned char get();}

    };

    // All getters of all properties

    String ^PropClass::Name::get(){return _name;}

    String ^PropClass::Number::get(){return _number;}

    unsigned char PropClass::CRC::get(){return _crc;}

     

     

    Thursday, May 15, 2008 10:51 PM

All replies

  •  

    Hi Useruser1

     

    Please allow me to define the parameters of your problem, if I may.

     

    Is the C++ program you have a dll? If so, do you have the source code?

     

    On the basis that you do have access to the source code and it is a dll, you will need to 'export' the methods defined in the C++ that you need to call from your C# so that .NET knows how to access them. With a little more code inside the C#, there shouldn't be a problem making calls to the C++. This is a technique known as Platform Interop. .NET provides a number of robust ways to perform this Interop using primarily the System.Runtime.InteropServices namespace.

     

    Assuming that the methods you need aren't already exported in the C++ code, you need to mark them as being so. This takes two steps.

     

    First, in the C++ project's header file, enter this code:

     

    Code Snippet
    #define DllExport   __declspec( dllexport )

     

     

    Then, for each method you wish to export, add this code to the beginning of the declaration. This specifies that the method should be made visible to the outside world (the DllExport part) and that C++ name mangling should not be used (extern "C"):

     

    Code Snippet

    extern "C" DllExport

     

     

    Now you can recompile your C++ and the methods you have marked will be visible to .NET.

     

    Inside the C# you can then, using the System.Runtime.InteropServices namespace, define the methods you wish to import from the C++. Ensure the compiled C++ dll is in the same directory as your compiled C# code however!

     

    This is performed using the dllimport attribute in a fashion similar to this:

     

    Code Snippet

    [DllImport("powrprof.dll", SetLastError=true)]

    public static extern UInt32 CallNtPowerInformation(

    Int32 InformationLevel,

    IntPtr lpInputBuffer,

    UInt32 nInputBufferSize,

    IntPtr lpOutputBuffer,

    UInt32 nOutputBufferSize

    );

     

     

    This code imports the 'CallNtPowerInformation' method which is exported from a C++ dll called 'powrprof.dll'. The method name, return type, and number and type of parameters must match the declaration inside the C++. Matching the C# import up with the C++ export can be tricky but again Microsoft provide features such as MarshalAs to give the greatest level of interoperability - essentially providing the conversion between types for you.

     

    You will need to produce code for each methods you wish to import from the C++ in a similar way to that shown above. Obviously the name of the dll will be different, as will the method declaration, but at that point you will be able to make calls from the C# to the C++ almost transparently.

     

    More information on this complex but rewarding topic can be found in the MSDN library under the heading 'accessing APIs with C#'.

     

    I hope this helps a little - if you need to know more information please post a reply and let me know.

     

    Best

     

    J

    Thursday, May 15, 2008 1:07 AM
  • if the C++ program is an application, you can use Process.StartInfo to invoke it with input arguments
    Thursday, May 15, 2008 3:03 AM
  • Interesting... the c++ code is an .exe application that I have created and I have the source code too.  I wanted to add a c# GUI to it which I have also created.  Will this method still work which you explained above?  I am assuming I will have to make some modifications since it is not a dll?

    Thanks!
    Thursday, May 15, 2008 2:27 PM
  • Ya I can do that but I would rather have the GUI as a way for me to input arguments and whatever other info for my C++ program to interpret and run accordingly.  The GUI was a way for me to choose certain options and aspects of the program I wanted to run.

    Thanks
    Thursday, May 15, 2008 2:29 PM
  • It's not particularly elegant but it sounds like the most simple way forward for you is to just make a call to the compiled c++ executable with command line parameters specified in the C# gui.

     

    You will need to make a change to your C++ code to accomodate taking in the command line parameters, and in the C# you need to do something like this:

     

    Code Snippet

    ProcessStartInfo myNewProcessStartInfo = new ProcessStartInfo();

    myNewProcessStartInfo.FileName = "name and location of the c++ executable";

    myNewProcessStartInfo.Arguments = "command line parameters to pass the new process";

    Process.Start(myNewProcessStartInfo);

     

     

    Depending on whether you have the opportunity to do so however I would consider making changes to your C++ code to create a dll instead which can be accessed by the C# code directly. It would be a more elegant solution but obviously only you know whether the time taken to make this change is worthwhile or necessary.

     

    I hope this helps - if you need more information please post again.

     

    Best

     

    J

    Thursday, May 15, 2008 9:59 PM
  •  

    Well, if you have the source you can write a wrapper. I have already done this, but i have had a dll. i created a new solution and added a new c# windows executable project and a new c++ CLR project. CLR means common language runtime and it has the /clr tag in compiler options that means it is compatible to c# (.NET). So if you write a wrapper you have to use special syntax and operator, but if you do, you can use your c++ functions in c# GUI as if they would be written in c# itself.

    Watch this little example of a c++ class, which is usable in c# as a normal class with normal properties...

     

    Code Snippet

    using namespace System;

    public ref class PropClass

    {

    private:

    String ^_name;

    String ^_number;

    unsigned char _crc;

    public:

    /*

    Constructor.

    */

    PropClass(String ^name,

    String ^number,

    unsigned char crc)

    {

    _name = name;

    _number = number;

    _crc = crc;

    }

    // Property forward deklaration

    property String ^Name{String ^get();}

    property String ^Number{String ^get();}

    property unsigned char CRC{unsigned char get();}

    };

    // All getters of all properties

    String ^PropClass::Name::get(){return _name;}

    String ^PropClass::Number::get(){return _number;}

    unsigned char PropClass::CRC::get(){return _crc;}

     

     

    Thursday, May 15, 2008 10:51 PM
  • Thanks.  This worked for me.

    Let me try using the dll strategy and see how it goes...
    Tuesday, May 20, 2008 6:29 PM
  • Ok so I got my code working 2 ways, as a .exe and using the ProcessStartInfo call from the C# GUI code to run the exe and also as a dll and making calls to my methods from the GUI code.
    Thanks for all the help!

    2 more small things...

    1.  I have trouble  passing std strings in my c++ methods as a dll and calling these methods form the C# code.  Char * works fine but std strings give me issues?  Any idea how I can fix this?

    2.  The other thing is in my c++ code, I do a system call to copy some files.  When the programs is run as an exe the copies are all done on one cmd window.  When the methods are called in dll form
    everytime a file is copied a new window pops open and then closes.  Any idea how to keep this all on one window?

    Thanks!!!
    Friday, May 23, 2008 2:56 PM
  • 1) You can't pass an instance of a class to a method from C# to C++.  Therefore, you can't use std:Tongue Tiedtring and will have to resort to char* or wchar_t*.

     

    2) Why are you using a "system" call?  Why not call the CopyFile API for example?  If there already is a console window, then the "system" call goes to that window; but if there isn't a console window, then the "system" call executes in a new window.  I strongly suggest that you don't use "system" calls unless you must.

     

    Friday, May 23, 2008 5:46 PM
  • Oh that makes sense.  I did not even know about the CopyFile API.  Let me try that.

    Thanks!
    Friday, May 23, 2008 6:22 PM
  • So I am having problems with the CopyFile method.
    If i pass it a hardcoded directorory like this it works

    [code]
    CopyFile("C:\\Documents and Settings\\temp.exe", "C:\\Documents and Settings\\Hello.exe",FALSE);
    [/code]

    However, if I have a directory stored as a std string and call c_str() on it my method does not work

    [code]
    CopyFile(dirPath.c_str(), "C:\\Documents and Settings\\Hello.exe",FALSE);
    [/code]

    Any idea what is going on?


    Thursday, May 29, 2008 5:51 PM
  • Do you get an exception or is it just that the file doesn't get copied?

     

    Can you check the result of the copy operation?

     

    J

     

    Thursday, May 29, 2008 5:58 PM
  • Ya nothing happens.  I am getting a return value from CopyFile of 1
    Thursday, May 29, 2008 6:03 PM
  • Ok I did a get last error and it responds back with a Access is denied?
    Thursday, May 29, 2008 7:24 PM
  • Ok nevermind.  Somehow I got it to work.  Thanks!
    Thursday, May 29, 2008 7:35 PM