Long time listener, first time caller. I\'m aware this is a somewhat obscure question, and don\'t expect too much. :-)
I have the following Ada files:
gr
I can't help with the Perl side (you require 5.14, Mac OS X has 5.12, Debian 6 has 5.10). That said, I can help with building the library for a C main and direct linking ...
The GNAT build process is sufficiently complicated that there are two tools to support it, gnatmake
and gprbuild
. It’s likely (writing at September 2015) that gnatmake
will lose the ability to build libraries, so gprbuild
is the better option.
I think you need a stand-alone library project (that is, one with the initialization and finalization operations that control Ada elaboration; if you don't initialize the Ada library, you'll get SEGVs or other bad behaviours). You'll find the lowdown on building one here.
The greeter.gpr
I wrote is
project Greeter is
for Library_Name use "greeter";
for Library_Kind use "relocatable";
for Library_Dir use "lib";
for Library_Interface use ("greeter");
for Library_Auto_Init use "true"; -- the default, I think
for Object_Dir use ".build"; -- to keep temp objects out of the way
end Greeter;
The Library_Name
attribute controls the name of the library; libgreeter.dylib
on Mac OS X, libgreeter.so
on Linux.
The Library_Kind
attribute could alternatively be "static"
, in which case the name would be libgreeter.a
. However, stand-alone libraries must be relocatable.
The Library_Dir
attribute, which you have to supply (with the two above) to make a library at all, controls where the library is created; in this case, in lib/
.
You have to supply the Library_Interface
attribute to make it a stand-alone library and generate the initialization and finalization operations that control Ada elaboration. They're called library_nameinit
and library_namefinal
- here, greeterinit
, greeterfinal
.
If Library_Auto_Init
is "false"
you have to call the initialization and finalization operations yourself, if "true"
, they're managed automagically.
OK, build the library by
gprbuild -p -P greeter
(-p
says "create any needed output directories", -P
specifies the project file).
I built greeter.c
#include <stdio.h>
extern void greeter_hello();
int main()
{
greeter__hello();
return 0;
}
using
$ gcc greeter.c -o greeter -L lib -l greeter
and run (on Linux) using
$ LD_LIBRARY_PATH=./lib ./greeter
I'll do the best I can with this, given not much Perl knowledge.
It looks to me like the Dynaloader in perl is a utility that lets you load dynamicly loadable libraries (lib*.so's on Unix systems) into a perl program.
For that to work for an Ada program, there are several things you'll need to take into account.
C_yourprogramname
, but don't hold me to that. Even if you are implementing a library of some sort, the elaboration should be run first (execpt in some special circumstances, that do not apply here). However, if you want a routine to be a library routine called from outside of Ada, you generally don't want a "main", so there are some extra steps. How to do this with Gnat is described in their user guide, but in general it involves telling the compiler to not make a "main", calling adainit
before running any Ada routine from outside, and calling adafinal
when you are all done.