comp.lang.ada
 help / color / mirror / Atom feed
* Plugin with controlled variable for initialization.
@ 2022-02-02 17:21 hreba
  2022-02-02 18:05 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 2+ messages in thread
From: hreba @ 2022-02-02 17:21 UTC (permalink / raw)


For the plugin scheme in my actual program I worked along the 
corresponding gnat example, but while the original works, mine doesn't. 
So I boiled it down to a minimum.

plugin.ads
----------

package Plugin is
    procedure Empty;
end Plugin;

plugin.adb
----------
with Ada.Finalization;
with Ada.Text_IO;

package body Plugin is

    type Life_Controller is new Ada.Finalization.Limited_Controlled with 
null record;
    overriding procedure Initialize (lc: in out Life_Controller);
    overriding procedure Finalize (lc: in out Life_Controller);

    procedure Empty is
    begin
       null;
    end Empty;

    overriding procedure Initialize (lc: in out Life_Controller) is
    begin
       Ada.Text_IO.Put_Line("Hello world!");
    end Initialize;

    overriding procedure Finalize (lc: in out Life_Controller) is
    begin
       Ada.Text_IO.Put_Line("Bye world!");
    end Finalize;

    lc:	Life_Controller;

end Plugin;

main.adb
--------
with System;
with Interfaces.C.Strings;
with Ada.Text_IO;

procedure Main is

    use type System.Address;
    RTLD_LAZY:	constant := 1;
    handle:	System.Address;

    function dlopen (Lib_Name: String; Mode: Interfaces.C.int)
		   return System.Address;
    pragma Import (C, dlopen, "dlopen");

begin
    handle:= dlopen ("../Plugin/lib/libplugin.so" & ASCII.NUL, RTLD_LAZY);
    if handle = System.Null_Address then
       Ada.Text_IO.Put_Line("unable to load plugin");
    end if;
end Main;


Main executes without any output. My understanding is the following:

  - When plugin loading with dlopen fails, I get an error message.
  - Otherwise, the controlled variable lc in plugin.adb comes to life and
    I get an output from the Initialize procedure.

Where is my misconception?
-- 
Frank Hrebabetzky, Kronach	+49 / 9261 / 950 0565

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Plugin with controlled variable for initialization.
  2022-02-02 17:21 Plugin with controlled variable for initialization hreba
@ 2022-02-02 18:05 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 2+ messages in thread
From: Dmitry A. Kazakov @ 2022-02-02 18:05 UTC (permalink / raw)


On 2022-02-02 18:21, hreba wrote:
> For the plugin scheme in my actual program I worked along the 
> corresponding gnat example, but while the original works, mine doesn't. 
> So I boiled it down to a minimum.
> 
> plugin.ads
> ----------
> 
> package Plugin is
>     procedure Empty;
> end Plugin;
> 
> plugin.adb
> ----------
> with Ada.Finalization;
> with Ada.Text_IO;
> 
> package body Plugin is
> 
>     type Life_Controller is new Ada.Finalization.Limited_Controlled with 
> null record;
>     overriding procedure Initialize (lc: in out Life_Controller);
>     overriding procedure Finalize (lc: in out Life_Controller);
> 
>     procedure Empty is
>     begin
>        null;
>     end Empty;
> 
>     overriding procedure Initialize (lc: in out Life_Controller) is
>     begin
>        Ada.Text_IO.Put_Line("Hello world!");
>     end Initialize;
> 
>     overriding procedure Finalize (lc: in out Life_Controller) is
>     begin
>        Ada.Text_IO.Put_Line("Bye world!");
>     end Finalize;
> 
>     lc:    Life_Controller;
> 
> end Plugin;
> 
> main.adb
> --------
> with System;
> with Interfaces.C.Strings;
> with Ada.Text_IO;
> 
> procedure Main is
> 
>     use type System.Address;
>     RTLD_LAZY:    constant := 1;
>     handle:    System.Address;
> 
>     function dlopen (Lib_Name: String; Mode: Interfaces.C.int)
>             return System.Address;
>     pragma Import (C, dlopen, "dlopen");
> 
> begin
>     handle:= dlopen ("../Plugin/lib/libplugin.so" & ASCII.NUL, RTLD_LAZY);
>     if handle = System.Null_Address then
>        Ada.Text_IO.Put_Line("unable to load plugin");
>     end if;
> end Main;
> 
> 
> Main executes without any output. My understanding is the following:
> 
>   - When plugin loading with dlopen fails, I get an error message.
>   - Otherwise, the controlled variable lc in plugin.adb comes to life and
>     I get an output from the Initialize procedure.
> 
> Where is my misconception?

Probably, you do not have automatic initialization of the Ada run-time.

    for Library_Auto_Init use "False";

Which is good, because under Windows would deadlock.

What you should do is:

1. Add an entry point to the library. Call it in order to return the 
expected minimum version of Main. It would add resilience. The 
implementation must be simple and not to require initialization. E.g.

    function get_required_version return Interfaces.C.unsigned;
    pragma Convention (C, get_required_version);

Use dlsym to get the address:

    type get_required_version_ptr is
       function return Interfaces.C.unsigned;
    pragma Convention (C, get_required_version_ptr);
    function dlsym
             (  handle : System.Address;
                symbol : char_array := "get_required_version" & NUL
             )  return get_required_version_ptr;
    pragma Import (C, dlsym);

2. Add another entry point like My_DLL_Init to call after version check. 
 From there first call to Ada run-time initialization. I believe it is named

    <library-name>init

After that you could do plug-in bookkeeping, calling registering 
subprograms etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-02-02 18:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-02 17:21 Plugin with controlled variable for initialization hreba
2022-02-02 18:05 ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox