comp.lang.ada
 help / color / mirror / Atom feed
From: Wiljan Derks <W.Derks@nl.cis.philips.com>
Subject: Re: gnat and dlls
Date: 1996/05/20
Date: 1996-05-20T00:00:00+00:00	[thread overview]
Message-ID: <31A0D559.712F@nl.cis.philips.com> (raw)
In-Reply-To: 4no2nu$60g@cville-srv.wam.umd.edu


Eric Anthony Spear wrote:
> 
> Is there any way I can write procedures in Ada, compile with gnat, and
> end up with a dll, which could then be accessed by a windows program,
> like visual basic?
> 

I wanted the same thing and I actually managed to do this. Finally I had a piece
of ada code (with tasking stuff inside) and I could call procedure in it from
visual basic.
I encountered several problem however:
  - The first think I tried was using the dlltool from cygnus.
    I run into trouble becuase you must also use the cygnus
    linker to link the dll. Trouble with that is that it is
    not able to link to MS libraries as the ld from labtek.
    so finally it meant it was not usable.
    The ld from labtek can also not link a dll.
    For that reason I switched to the MS linker. You can setup
    gnat on NT so that it uses that linker.
  - Finally I made an ada package with a task inside.
    To link it I first made a program that calls a procedure from
    that package using the ms linker. This gives you an .gp file
    that contains a link script for that program.
    Then you can use gnatbind to generate a c file that just does
    an initialisation. (use gnatbind with -n option).
    You can the edit the .gp file and remove the obj for the
    main program you originally had and add the object for the
    generated c bind code. That code contains an adainit procedure
    that initializes the ada environment.
    The you can link using the addapted .gp file and use the same
    options and arguments that are normally used when linking with
    the ms linker. (just try -v options and you will see them when
    you normally link a program.) Beside those you must also specify the
    -dll option and the -def:dll.def option.
    In my case the dll.def file contained:

LIBRARY
	dll
EXPORTS 
	_addint@8
	_dll_entry@12
	_trydll_init@0

     The MS linker then generates the the dll in one step. You can find the
     ms linker on ftp.microsoft.com somewhere. It is a bugfix for an old linker
     and it actually works. You will not get decent error messages from it when
     there is an error however bcuase it is incomplete. Up to now I had not
     change to try it with msvc.

     Using NT 4.0 is easy because it allows you to peek inside .dll and .exe
     files using the explorer right mouse button. It will show you the
     entry points that are in there.


The code that I use to try this is attached at the end of this
message. I just put in a task that increments a variable periodically.
This allows you to show all features from the visual basic program.
In visual basic I declare the functions as:

Private Declare Function addint Lib "\users\wiljan\ada\trydll\dll" Alias "_addint@8" (ByVal a As 
Long, ByVal b As Long) As Long
Private Declare Sub initdll Lib "\users\wiljan\ada\trydll\dll" Alias "_trydll_init@0" ()

I had to put a few extra procedure in my package it to make the
linker happy:
   - Routine main and main_priotity. This are required when you want to link ada code.
   - dll_entry. I linked this in the dll as the entry point for the dll.
     (more on that one later)
   - two routine which I called later from visual basic: addint and trydll_init
I originally wanted to make a dll which initialises itself automatically.
This is done on NT becuase the entry point is called when a process attaches to a
dll. In that case b=1. This however did not work. Probably some deadlock arizes
becuase of the tasking inside the ada code. It looks like:
   - Because of the dll load the initialisation creates a task and waits on it.
   - Probably the taks needs to wait for the dll initialisation before it can
     be run, hence the deadlock that occurs in this situation.
     everything works fine when not using tasking in the package.
I know it is a big hack, but when first calling the init function once from
visual basic everything worked fine.
A last problem that I had was when exiting the visual basic program.
It simply does not apear form the system (the form did). This is becuase of the
tasking still some threads are running which causes the program not to exit.
This is a general problem when using ada programs with tasking. I think it is
best to simply call exitprocess (i do not know if that is the right name) directly.

Lets hope Labtek addapt the linker a bit so that things will get much simpler
in the near future. For visual basic it is a must that you link packages into
a dll, but also for the run time it whould be nice to be able to put stuff
into a dll somehow. To make a general solution for this is not that trival however.

Wiljan


package trydll is

function addint(a,b:integer) return integer;
function dll_entry(a,b,c:integer) return integer;
procedure trydll_init;

pragma convention(stdcall,addint);
pragma convention(stdcall,dll_entry);
pragma convention(stdcall,trydll_init);
pragma export(C,addint,"addint");
pragma export(C,dll_entry,"dll_entry");
pragma export(C,trydll_init,"trydll_init");

end trydll;
package body trydll is

glob:integer:=0;

function addint(a,b:integer) return integer is
begin
   return a+b+glob;
end addint;

procedure adainit;
pragma import(C,adainit,"adainit");

procedure trydll_init is
begin
   adainit;
end trydll_init;

adainit_done:boolean:=false;

function dll_entry(a,b,c:integer) return integer is
begin
   if b=1 and not adainit_done then
--      adainit;
      adainit_done:=true;
   end if;
   return 1;
end dll_entry;

task increment;
task body increment is
begin
   loop
      delay 1.0;
      glob:=glob+1;
   end loop;
end increment;

procedure main;
pragma export(C,main,"main");
procedure main is
begin
   null;
end main;

function main_priority return integer;
pragma export(C,main_priority,"__main_priority");
function main_priority return integer is
begin
   return -1;
end main_priority;

end trydll;




  parent reply	other threads:[~1996-05-20  0:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1996-05-19  0:00 gnat and dlls Eric Anthony Spear
1996-05-19  0:00 ` Tom Griest
1996-05-20  0:00   ` Darren C Davenport
1996-05-20  0:00 ` Wiljan Derks [this message]
1996-05-22  0:00   ` gnat and dlls: ObjectAda Dave Wood
1996-05-20  0:00 ` gnat and dlls John Howard
1996-05-21  0:00 ` Doug Warner
replies disabled

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