2

This is more a design than an implementation question. I am aware of how to integrate a C++ DLL within a C# main app that acts as GUI. Believe me that I've read all other questions on similar topics, but none of them clearly answer my question, so here we go:

  • I have a C++ DLL with a few functions that interact with an API to another system (black box for me). The function that connects to the API must be "alive" whilst the whole program is running, otherwise connection to the API is lost and everything becomes more difficult. So, bare in mind that if I call the "Connect" function in the DLL and then I return to C# code, the DLL code will be out of context (no longer under execution), and disconnection will occur (correct me if I'm wrong please).

  • So far it seems that what I need is:

    a) Call the C++ DLL functions using P/Invoke as usual

    b) Design a mechanism that keeps the DLL function (including calls to other functions within the DLL running all the time)

    c) Each time the C++ DLL module has new fresh data, callback the C# and update all necessary data for presentation.

It seems easy, but I don't manage to make the design in a way that none of them gets stuck. I've tried using infinite loops in the C++ DLL side, but then the GUI gets stuck. If I just perform a call to the DLL every "x" seconds, then I'm polling too many unnecessary times and the GUI becomes slow and not elegant in the refreshing. Besides, having the GUI as the "master" and the DLL as the "slave" results in disconnections because of DLL stopping execution whilst in C# code context.

Don't be too hard with me guys, I know there must be some simple design issue that I am not considering, but I can't find out what is it. I am new on C#, not on C++.

Also, I would appreciate if you could suggest another solution for a case where refreshing data from the DLL side would be almost real time, just like reading instant speed of a vehicle in real time.

11
  • 4
    Do you know what threads are? If not, look into that! And if you do know, perhaps explain why they don't solve your problem.
    – hyde
    Commented Aug 24, 2015 at 15:26
  • 3
    How exactly this should be solved depends on the DLL. If you can add some code which shows how DLL is used correctly without GUI (single thread, blocking, whatever), then you might get answer telling how to use it with GUI correctly. As it is, the question is very hard to answer meaningfully.
    – hyde
    Commented Aug 24, 2015 at 15:42
  • 5
    You wrote - the function that connects to the API must be "alive" - but what does that mean (even if there is no GUI involved)? How exactly do you open a connection, how do you close the connection, and how does the external system know that the "client" is still alive? Do you have to send "keep-alive" packages in regular intervals? I recommend you sketch an example. Though threads might be part of the solution, IMHO it does not make sense to talk about threads if it is not clear what must happen inside the thread.
    – Doc Brown
    Commented Aug 24, 2015 at 21:10
  • 1
    @karakol: you did not answer my question, and you did not answer hyde's question as well. Sketch an example without GUI, and we tell you how to combine it with GUI.
    – Doc Brown
    Commented Aug 25, 2015 at 13:55
  • 2
    After two years this old question was bumped to the home page - still I see nothing of the promised example, and still no clarification of the obviously wrong assumptions. So voting to close as "unclear" now, I don't see that this question will ever be clarified.
    – Doc Brown
    Commented Oct 13, 2017 at 21:38

2 Answers 2

1

a) Call the C++ DLL functions using P/Invoke as usual

This indicates that the OP did not read all there is.

P/Invoke is fine as it goes, but for more complex scenarios, a C++/CLI layer is far more appropriate, especially when it comes to callbacks into .NET.

The rest of the question IMHO cannot be answered without further detail from the OP, so I'll leave it at that.

0

It's not at all clear what you're trying to accomplish, but fortunately it doesn't really matter, as the C# and C++ integration aspect really doesn't play into it with respect to managing your asynchronous function calls.

Whether you use DllImport, (PInvoke), C++/CLI or something else, it really doesn't matter, as the state of the DLL innards is preserved between function calls.

So, bare in mind that if I call the "Connect" function in the DLL and then I return to C# code, the DLL code will be out of context (no longer under execution), and disconnection will occur (correct me if I'm wrong please).

This is not true. Let's look at an example. Create a simple DLL:

int foo = 5;

extern "C"
{
    __declspec(dllexport) int GetFoo()
    {
        return foo;
    }

    __declspec(dllexport) void SetFoo(int f)
    {
        foo = f;
    }

    __declspec(dllexport) int GetFooSquared()
    {
        return foo * foo;
    }
}

Then let's create a C# app that access those functions:

class Program
{
    [DllImport("MyLibrary.dll")]
    static extern int GetFoo();
    [DllImport("MyLibrary.dll")]
    static extern void SetFoo(int b);
    [DllImport("MyLibrary.dll")]
    static extern int GetFooSquared();

    static void Main(string[] args)
    {
        Console.WriteLine("Get foo {0}", GetFoo());

        SetFoo(7);
        Console.WriteLine("Get foo {0}", GetFoo());
        Console.WriteLine("Get foo squared {0}", GetFooSquared());
    }
}

And if we run it, our foo variable in the dll will be modified, and the modified value will be preserved across function calls. When the C# library starts up, when the first call to MyLibrary.dll takes place, the library is loaded and its memory space stays loaded.

Running the example we get an expected output indicating state is preserved:

 Get foo 5
 Get foo 7
 Get foo squared 49

So, structure your design imagining how you'd do it if it was all in one language, C# or C++. Whatever design you come up with, the only modification you need to make it work is to cross the C#/C++ boundary. The options to do that is to write a C++/CLI class to map data structures back and forth, or to pipe everything across C style function calls, but those are not very difficult, and there's a variety of ways to make it work.

But ultimately you do not need any busy waiting loops or anything of that such because your DLL won't "disconnect" without you going through some serious hoops to make it do so intentionally.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.