Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Notifying about events from dll to main app

I am developing application which intend to be cross platform. I used to use Windows Messages but now I am dropping it out. I replaced messages with callbacks but regardless I can use different technologies I am not aware of different possibilites when not using windows messages.

Well I have main exe aplication and some dll plugins. I have some objects and threads in dll and I would like to notify main application about some changes that DLL made to data structure.

As I said I am currently working with some callbacks. To provide compatibility with different languages (C++, VB, C#) I have non-object type of callback. I am not sure if other languages supports callback of object.

So my questions are:

  • What are the alternatives (cross-platform) to windows messages? Can callbacks replace messages?
  • Do other languages support callback of object?
  • I guess other languages have different technologies as alternative to messages?
like image 378
Nix Avatar asked Dec 17 '22 02:12

Nix


2 Answers

You can certainly use callback functions instead of messages. You can't use callback methods because only Delphi and C++ Builder understand how to invoke Delphi method pointers. However, you can use callback objects with any language that supports COM. Here's an example for a plug-in to notify the application that the data structure has changed:

  1. Define an interface.

    type
      IDataStructureChanged = interface
        ['{GUID}']
        procedure Call; stdcall;
      end;
    

    You could add some parameters to the method so the plug-in can tell how the data structure changed, or pass some value indicating which plug-in is making the notification.

  2. Implement it in the application.

    type
      TDataStructureChangedListener = class(TInterfacedObject, IDataStructureChanged)
      private
        FForm: TForm;
        procedure Call; stdcall;
      public
        constructor Create(Form: TForm);
      end;
    

    When you instantiate that class, you can pass it a reference to your program's main form, or whatever other information your program will need to be able to take action when a plug-in eventually calls the Call method. Implement Call to make your application do whatever it needs to do when a data structure changes.

  3. Pass a reference to each of the plug-ins when you initialize them.

    ChangeListener := TDataStructureChangedListener.Create(Self);
    for i := 0 to Pred(PlugIns.Count) do
      PlugIns[i].Init(ChangeListener);
    

    The plug-in should store a reference to the listener object, and when the data structure changes, it can call the Call method to notify your application.

What I've described here is what's generally known as an event sink. You can have more than one in your program. If there are multiple events to handle, you could have a separate interface for each kind of event, or you could group them all into a single interface and have a different method for each event. You could have a different sink object for each plug-in, or you could give each plug-in a reference to the same sink object, and then pass a plug-in-ID parameter.

like image 166
Rob Kennedy Avatar answered Dec 27 '22 21:12

Rob Kennedy


I would definately use callbacks. The main app could give a callback function to the DLL to call when needed, and then the callback function itself can send window messages to the app if it needs to.

like image 32
Remy Lebeau Avatar answered Dec 27 '22 19:12

Remy Lebeau