gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gm2] Calling Modula-2 from C


From: Iztok Kobal
Subject: Re: [Gm2] Calling Modula-2 from C
Date: Wed, 03 Jun 2009 01:54:20 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.21) Gecko/20090410 SUSE/1.1.16-1.2 SeaMonkey/1.1.16

With XDSM2, story goes like this:

A.def:
DEFINITION MODULE A;
PROCEDURE a;
END A.

A.mod:
IMPLEMENTATION MODULE A;
IMPORT STextIO;
PROCEDURE a;
BEGIN
  STextIO.WriteString("Hello from M2 World");
  STextIO.WriteLn;
END a;
BEGIN
  STextIO.WriteString("Initializing M2 module A");
  STextIO.WriteLn;
END A.

MyLib.def:
DEFINITION MODULE MyLib;
END MyLib.

MyLib.mod:
IMPLEMENTATION MODULE MyLib;
IMPORT A;
(* here on we should list and import all M2 modules we possibly have
defined and wanted in our future library - right now only A is here*)
BEGIN
END MyLib.

main.mod:
MODULE main;
IMPORT MyLib;
IMPORT A; (* this line is not really needed - just for IO demo *)
BEGIN
 A.a; (* this line is not really needed - just for IO demo *)
END main.

build:
xc =make main.mod

Note that for 64bit platforms you will probably have to modify resulting
tmp.mkf with adding -m32 to the CC and LFLAGS definitions and run "make
-f tmp.mkf main" for final linking

We have built M2 native binary which we need for comparission with C
native binary. Running it results in:
> main
Initializing M2 module A
Hello from M2 World

which is what we expected, really.

Now, with C:

mainc.c:
extern void X2C_BEGIN(int*, char**, int, long, long); /* XDS M2RTS
initialization entry point */
extern void MyLib_BEGIN(void); /* MyLib & dependencies initialization
bodies entry point */
extern void A_a(void); /* the real stuff - the function we are doing
this salto mortale for */

int main(int argc, char** argv) {
  X2C_BEGIN(&argc,argv,1,0l,8000000l);
  MyLib_BEGIN();
  A_a();
  return 0;
}

gcc -c -g3 -O0 -m32 -o mainc.o mainc.c
gcc -m32 -g3 -O0 -o mainc mainc.o MyLib.o A.o $XDSROOT/lib/x86/libxds.a -lm

Note: again, -m32 stands here to build 32bit code on 64bit platforms
since XDS is 32bit therefore it is only relevant for 64bit platforms

running the program, again shows us desired result:
> mainc
Initializing M2 module A
Hello from M2 World

Well, this is for statically linked programs.

For DLLs, the procedure is exactly the same. Link the "MyLib.o A.o
$XDSROOT/lib/x86/libxds.a -lm" into the shared library called e.g. MyLib:

gcc -shared -m32 -g3 -O0 MyLib.o A.o
/home/kiztok/m2/xds/lib/x86/libxds.a -lm -o MyLib.so.0.0.0

link it against old mainc.o, yet now producing other binary called maincso:

gcc -m32 -g3 -O0 -o maincso mainc.o MyLib.so.0.0.0

again, running maincso produces desired result:
> maincso
Initializing M2 module A
Hello from M2 World

some other data:
> ls -al main*
-rwxr-xr-x 1 kiztok users 324221 2009-06-03 00:58 main
-rwxr-xr-x 1 kiztok users  94636 2009-06-03 01:02 mainc
-rwxr-xr-x 1 kiztok users  12451 2009-06-03 01:31 maincso

ls -al MyLib.so.0.0.0
-rwxr-xr-x 1 kiztok users 122643 2009-06-03 01:30 MyLib.so.0.0.0

> ldd main
        linux-gate.so.1 =>  (0xffffe000)
        libm.so.6 => /lib/libm.so.6 (0xf7eaa000)
        libc.so.6 => /lib/libc.so.6 (0xf7d77000)
        /lib/ld-linux.so.2 (0xf7efa000)

> ldd mainc
        linux-gate.so.1 =>  (0xffffe000)
        libm.so.6 => /lib/libm.so.6 (0xf7f2f000)
        libc.so.6 => /lib/libc.so.6 (0xf7dfc000)
        /lib/ld-linux.so.2 (0xf7f7f000)

> ldd MyLib.so.0.0.0
        linux-gate.so.1 =>  (0xffffe000)
        libm.so.6 => /lib/libm.so.6 (0xf7f3b000)
        libc.so.6 => /lib/libc.so.6 (0xf7e08000)
        /lib/ld-linux.so.2 (0x56555000)

> ldd maincso
        linux-gate.so.1 =>  (0xffffe000)
        MyLib.so.0.0.0 => .............../MyLib.so.0.0.0 (0xf7f86000)
        libc.so.6 => /lib/libc.so.6 (0xf7e29000)
        libm.so.6 => /lib/libm.so.6 (0xf7e04000)
        /lib/ld-linux.so.2 (0xf7fb8000)


I hope this helps! I would suppose that for XDS O2 should be very much
alike.

Of course, things differ from one M2 environment to another since M2RTS
initialization is unique for each and every one. I have done this C/M2
marriage with GPM2 and of course StonyBrookM2 on Wins.

Regards, Iztok




Ron Kneusel wrote:
> Iztok, Gaius-
>
> Ok, my further experiments with XDS M2 now make sense.  I was able to
> call a simple module that only multiplied two numbers together but
> unable to call any InOut functions because the initialization was
> missing. 
>
> Iztok, do you have source files already set up for XDS M2 with your
> library trick?  I can piece it together myself, now that I know what
> to do, but it might save some time if you are willing to share them.
>
> I used to work with Modula-2 in the 1990s (MacMETH on the Macintosh)
> and wanted to use it again to add extensions to IDL (www.ittvis.com)
> which I've done in the past in FORTRAN using a C wrapper.  This is
> partly for fun and partly for demonstration purposes.  If I get XDS to
> work, I can probably use Oberon-2 as well.
>
> Gaius, thank you also for the comments and taking the time to reply to
> my queries.
>
> Ron
>
> > Date: Mon, 1 Jun 2009 08:57:52 +0200
> > From: address@hidden
> > To: address@hidden
> > CC: address@hidden; address@hidden
> > Subject: Re: [Gm2] Calling Modula-2 from C
> >
> > Ihave been using a simple trick to resolve also dependencies in more
> > simple way.
> >
> > I have organized a library module calling all modules. Its init body
> > certainly calls all init bodies of all linked modules in appropriate
> > order. So:
> >
> > At start I had pool of M2 modules:
> >
> > DEFINITION/IMPLEMENTATION MODULE A
> > DEFINITION/IMPLEMENTATION MODULE B
> > ...
> > DEFINITION/IMPLEMENTATION MODULE N
> >
> > Here comes the master library module - we need it to have resolved
> > dependency modules and proper init sequence. It should also be arranged
> > as DEF/IMP module to make init body exported:
> >
> > DEFINITION MODULE MyM2Lib;
> > END MyM2Lib;
> >
> > IMPLEMENTATION MODULE MyM2Lib;
> > IMPORT A;
> > IMPORT B;
> > ...
> > IMPORT N;
> > BEGIN
> > END MyM2Lib;
> >
> >
> > And here comes main module calling M2M2Lib's init body to have it public
> > in symbol list since linker would not exclude it as unused:
> >
> > IMPLEMENTATION MODULE MyM2LibMain;
> > IMPORT MyM2Lib;
> > BEGIN END MyM2LibMain.
> >
> >
> > Now, from C, the procedure is:
> >
> > main() {
> > MyM2Lib_init(); /* call M2 lib's init sequence, different for each M2
> > compiler, for GM2 should look something like _M2_MyM2Lib_init(...) */
> >
> > /* now we can use functions from lib - also the symbol generated
> > depends on M2 compiler */
> > A_foo(...);
> > etc.
> > }
> >
> >
> > Described method worked for XDSM2, GPM2 and StonyBrookM2 (which BTW was
> > the only that supported libraries natively) so I suppose it should be
> > good for GM2 too. If I had to support different platforms using
> > different M2 compiler, the function symbols generated by these compilers
> > were obviously different so I ended up with bunch of define clauses
> > separated by conditional compiling variables. Pretty messy, though
> > successfuly working.
> >
> > Regards, Iztok
> >
> >
> >
> >
> > Gaius Mulley wrote:
> > > Ron Kneusel <address@hidden> writes:
> > >
> > >
> > >>> at present it is probably easier to make Modula-2 call C. Thus
> > >>> allowing Modula-2 to create the main function. So you might
> write the
> > >>> C module as:
> > >>>
> > >> Thanks for the reply. Unfortunately, that won't work in my case.
> I am looking
> > >> to use Modula-2 to write extensions for an existing C application and
> > >> ultimately I need to create a shared object. I have been playing
> with XDS
> > >> Modula-2 as well and have succeeded in going a bit further. I can
> compile and
> > >> link without trouble but get a segmentation fault when I try to call
> > >> WriteString().
> > >>
> > >
> > > Hi,
> > >
> > > ok, you can generate shared libraries using gm2. There are some
> > > examples in:
> > >
> > > gcc-4.1.2/gcc/gm2/examples/swig/full-strlib/
> > >
> > > which compile StrLib as a shared library, then links it to produce
> > > _StrLib.so and proceeds to make python call StrLen. There are also
> > > some screencasts available here:
> > >
> > >
> http://floppsie.comp.glam.ac.uk/download/screencasts/gnu-modula-2/python/python-numberio.mp4
> > >
> > > which show it in action.
> > >
> > > If you want to make your C application call Modula-2 it is possible -
> > > but you have to manually resolve the module dependencies and call the
> > >
> > > _M2_modulename1_init(argc, argv);
> > > _M2_modulename2_init(argc, argv);
> > >
> > > it is now safe to call modulename2_myfunc() etc
> > >
> > > _M2_modulename2_finish(argc, argv);
> > > _M2_modulename1_finish(argc, argv);
> > >
> > > in a sensible sequence. I'd suggest manually using gm2l to generate
> > > the dependencies sequence (it does this based on imports) and then
> > > adjust the order by hand and then using that to build the above
> > > initialisation. You can also use gm2lorder to fix the critical
> > > runtime order of SYSTEM, M2RTS and EXCEPTIONS. Finally you could also
> > > use gm2lgen to generate the above init/finish code and maybe adjust it
> > > to fit your application..
> > >
> > > regards,
> > > Gaius
> > >
> > >
> > >
> > >
> > > _______________________________________________
> > > gm2 mailing list
> > > address@hidden
> > > http://lists.nongnu.org/mailman/listinfo/gm2
> > >
> > >
> >
>
> ------------------------------------------------------------------------
> Lauren found her dream laptop. Find the PC that’s right for you.
> <http://www.microsoft.com/windows/choosepc/?ocid=ftp_val_wl_290>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]