AU-programs: replies

Alexej Jerschow (Alexej.Jerschow@mr.unit.no)
Mon, 13 Nov 1995 13:27:26 +0100

Dear All,
Some people have asked me to post the replies which I get on the question
about AU-programs. Here they are:

(Thank you, Guenter Schmidt and Andreas Huennebeck, for the answers)

-----------------------------------------------------------------

On Nov 9, 10:55am, Guenter Schmidt wrote:
> Subject: Re: AU program for data processing in Xwinnmr
> >
> > Dear All,
> > I would like to write an AU program for processing data in 2rr files
using
> > the xwinnmr program on an SGI (R4000, Irix 5.3, or R8000, Irix 6.0.1). To
do
> > this I would need some advice and clarification of the following
> >
> > 1) Can I write AU programs in a way that I can run them without xwinnmr
(e.g.
> > for testing). What changes are then to be made to make them run from within
> > xwinnmr again ?
>
> No, this is not possible.
> >
> > 2) Can I write the programs using the GNU Compiler and/or Libraries ?
>
> Is possible with the following changes in /u/exp/stan/nmr/au/makeau:
> 60c60,61
> < LDOPT="-s" ## default link option
> ---
> > LDOPT="" ## default link option
> > CC=gcc
> 289c290
> < cc -c -cckr -DIRIX_5_1 $INCLUDE $CCOPT $CPPOPT $DEFINE
-DOLD_META_MEMORY $srcdir/$PNAME.c
> ---
> > $CC -c -DIRIX_5_1 $INCLUDE $CCOPT $CPPOPT $DEFINE -DOLD_META_MEMORY
$srcdir/$PNAME.c
>
> >
> > 3) Can I use a Debugger when compiling AU programs from within xwinnmr ?
>
> Do a link or symlink of /u/exp/stan/nmr/au/makeau => /u/exp/stan/nmr/au/dbxau
> cd /u/exp/stan/nmr/au
> ln -s makeau dbxau
>
> Then compile with:
> ./dbxau <AU_program>
>
> Example:
> ./dbxau au_zg
> Compiling AU program au_zg for debugging.
> Linking au_zg
> /u/prog/xwin-nmr1.0/mod/a.out: 644 mode. Remove ? (yes/no)[no] :
> Cannot create /u/prog/xwin-nmr1.0/mod/a.out: File exists
>
> AU program au_zg is started with dbx debugger control.
> The first breakpoint is set to entry AU_program and the
> program is started for debbuging with 'r sdb'.
>
> Type within uxnmr the command 'a.out'
> [2] Process 624 (a.out) stopped at [main:58 ,0x403c24]
> 58 Start_unimar(argc,argv,(WRUPROC)0);
> Process 624: [3] stop in AU_program
> Process 624 (a.out) terminated
> Process 625 (a.out) started
> sdb: CPR_object = /u/prog/xwin-nmr1.0/curdir/gsc/cd.625
>
> You must create the file /u/prog/xwin-nmr1.0/mod/a.out, if it does not yet
exist.
> touch /u/prog/xwin-nmr1.0/mod/a.out ( as root, due to permissions )
>
>
> >
> > 4) Can I define subroutines ?
>
> Shure, have a look into the testsuite - AU - program. AU-programes is
standard
> C-code, exept that a lot of functions and subroutine calls are defined as
macros
> in /u/prog/xwin-nmr1.0/include/aucmd.h and also as included files
> in /u/exp/stan/nmr/au/inc ( which are evaluated by the submacro- command
within makeau.
>
> >
> > 5) Can I include C++ code ?
>
> In the same file, I dont think.
>
> >
> > 6) Can I run AU commands in queues ? (So that the user can specify to run
time
> > intensive processes sequentially)
> >
>
> You may execute them with XAU("au-program-name") within your AU program.
>
> > 7) Do there exist AU program libraries to take as an example other than the
> > ones
> > that come with the normal xwinnmr distribution ?
> >
> > 9) Do there exist predefined functions to access easily rows and cols in a
> > processed (2rr) 2D file ? (Read and write)
>
> Not in the delivered libraries in /u/prog/xwin-nmr1.0/lib directory.
>
> >
> >
> > I would be very glad if someone could give me an answer to the above
questions.
> >
> > Thank you very much
> >
> > Regards
> >
> > Alexej Jerschow
> >
> > --
> > ------------------------
> > Alexej Jerschow
> >
> > present address:
> >
> > MR-Center, SINTEF UNIMED
> > N-7034 Trondheim, Norway
> > Tel: +47-73 99 89 36
> > Fax: +47-73 99 77 08
> >
>
>
> --
> ==================================================================
> ... ... Dr. Guenter Schmidt
> . * . . Software Department
> . . . . Bruker Analytische Messtechnik GmbH
> B R U K E R D-76287 Rheinstetten
> . . . .
> . * . . Voice: +49 721-5161-443 Fax: +49 721-5161-437
> ... ... or: +49-721-95153-443 Fax: +49-721-95153-437
> E-Mail: gsc@bruker.de
> ==================================================================
>-- End of excerpt from Guenter Schmidt

On Nov 9, 11:52am, Andreas Huennebeck wrote:
> Subject: Re: AU program for data processing in Xwinnmr
> Dear Mr. Jerschow,
>
> we tried to answer your questions as precisely as possible, but nevertheless
we
> have not tried everything by ourself so there still may be the need to
explore
> things further on your own.
>
> > I would like to write an AU program for processing data in 2rr files
using
> > the xwinnmr program on an SGI (R4000, Irix 5.3, or R8000, Irix 6.0.1). To
do
> > this I would need some advice and clarification of the following
> >
> > 1) Can I write AU programs in a way that I can run them without xwinnmr
(e.g.
> > for testing). What changes are then to be made to make them run from
within
> > xwinnmr again ?
>
> No, this is not possible.
>
> > 2) Can I write the programs using the GNU Compiler and/or Libraries ?
>
> This is possible with the following changes in /u/exp/stan/nmr/au/makeau:
> 60c60,61
> < LDOPT="-s" ## default link option
> ---
> > LDOPT="" ## default link option
> > CC=gcc
> 289c290
> < cc -c -cckr -DIRIX_5_1 $INCLUDE $CCOPT $CPPOPT $DEFINE
-DOLD_META_MEMORY $srcdir/$PNAME.c
> ---
> > $CC -c -DIRIX_5_1 $INCLUDE $CCOPT $CPPOPT $DEFINE -DOLD_META_MEMORY
$srcdir/$PNAME.c
>
> > 3) Can I use a Debugger when compiling AU programs from within xwinnmr ?
>
> Do a link or symlink of /u/exp/stan/nmr/au/makeau => /u/exp/stan/nmr/au/dbxau
> cd /u/exp/stan/nmr/au
> ln -s makeau dbxau
>
> Then compile with:
> ./dbxau <AU_program>
>
> Example:
> ./dbxau au_zg
> Compiling AU program au_zg for debugging.
> Linking au_zg
> /u/prog/xwin-nmr1.0/mod/a.out: 644 mode. Remove ? (yes/no)[no] :
> Cannot create /u/prog/xwin-nmr1.0/mod/a.out: File exists
>
> AU program au_zg is started with dbx debugger control.
> The first breakpoint is set to entry AU_program and the
> program is started for debbuging with 'r sdb'.
>
> Type within uxnmr the command 'a.out'
> [2] Process 624 (a.out) stopped at [main:58 ,0x403c24]
> 58 Start_unimar(argc,argv,(WRUPROC)0);
> Process 624: [3] stop in AU_program
> Process 624 (a.out) terminated
> Process 625 (a.out) started
> sdb: CPR_object = /u/prog/xwin-nmr1.0/curdir/gsc/cd.625
>
> You must create the file /u/prog/xwin-nmr1.0/mod/a.out, if it does not yet
exist.
> touch /u/prog/xwin-nmr1.0/mod/a.out ( as root, due to permissions )
>
>
> > 4) Can I define subroutines ?
>
> Shure, have a look into the testsuite - AU - program. AU-programes is
standard
> C-code, exept that a lot of functions and subroutine calls are defined as
macros
> in /u/prog/xwin-nmr1.0/include/aucmd.h and also as included files
> in /u/exp/stan/nmr/au/inc ( which are evaluated by the submacro- command
within makeau.
>
> > 5) Can I include C++ code ?
>
> There are two possibilities:
> A. Have C++ Code within the AU program:
> 1. You must use g++ or c++ for compiling the AU program (see Point 2 above
> to enable this accordingly)
> 2. As C++ compilers use name mangling it is necessary to put the statement
> extern "C" {}
> around the declarations of all external C functions, e.g.
>
> #ifdef __cplusplus
> extern "C" {
> #endif
>
> #include <any-bruker-include-file>
> extern void free(void *);
>
> #ifdef __cplusplus
> }
> #endif
>
> and you must not forget the include files. For this you must change the
> file /u/exp/stan/nmr/au/vorspann accordingly (and we recommend to make
> a backup copy first!).
>
> Otherwise the linker tries to find the functions declared as extern
with
> mangled names, which do not exist in the C libraries.
>
> B. Use C++ libraries:
> This is somewhat simpler. You just have to
> - write a C-interface for each C++ function you want to use,
> - compile this interface with the C++ compiler,
> - add the object file into the C++ library (or any other library) and
> - link this library together with the AU program
> There exists a short documentation about how to write a C-interface for
> a C++ class. Unfortunately it's written in german language, but the code
> presented should be clear enough to understand anyway. Therefore we have
> added it at the end of this mail.
>
> > 6) Can I run AU commands in queues ? (So that the user can specify to run
time
> > intensive processes sequentially)
>
> You may execute them with XAU("au-program-name") within your AU program.
>
> > 7) Do there exist AU program libraries to take as an example other than the
> > ones that come with the normal xwinnmr distribution ?
>
> Not from Bruker.
>
> > 9) Do there exist predefined functions to access easily rows and cols in a
> > processed (2rr) 2D file ? (Read and write)
>
> Not in the delivered libraries in /u/prog/xwin-nmr1.0/lib directory.
>
> We wish you good success.
> Best regards (Ha det bra)
>
> Dr. Schmidt and A. Huennebeck
> --
> ========================================================================
> ... ... Dr. Guenter Schmidt
> . * . . Software Department
> . . . . Bruker Analytische Messtechnik GmbH
> B R U K E R D-76287 Rheinstetten
> . . . .
> . * . . Voice: +49 721-5161-443 Fax: +49 721-5161-437
> ... ... or: +49-721-95153-443 Fax: +49-721-95153-437
> E-Mail: gsc@bruker.de
> =========================================================================
> =========================================================================
>
> ... ... Andreas C. M. Huennebeck
> . * . . Software Engineer
> . . . . Bruker Analytische Messtechnik GmbH
> B R U K E R D-76287 Rheinstetten, Germany
> . . . . Tel : 49 (721) 5161-444
> . * . . Fax : 49 (721) 5161-437
> ... ... email: ah@bruker.de
>
> =========================================================================
>
>
>
> --- snip ----- snip ----- snip ----- snip ----- snip ----- snip ---
>
> Erstellen eines C-Interfaces zu C++ Klassenbibliotheken
> *******************************************************
>
> 1. Einführung
> ==============
> Da ein C-Compiler nicht in der Lage ist, C++ Code zu verstehen, kann ein
> C-Programm C++ Bibliotheken nicht ohne weiteres benutzen, da die
entsprechende
> C++ Headerdatei nicht angezogen werden kann. Glücklicherweise ist der Linker
> in der Lage, C++ und C-Objektdateien zu verbinden und die Aufrufe richtig zu
> verknüpfen. Man muß also nur noch ein Interface in C schaffen.
>
> Gegeben sei als Beispiel die Klasse Foo mit folgendem Interface in Foo.h:
>
> // Foo.h : C++ interface to class Foo
>
> class Foo
> {
> public:
> Foo(int i, double d);
> int getInt();
> double getDouble();
> };
>
>
> 2. Konstruktion der C-Headerdatei
> ==================================
> Es muß jetzt für jede öffentliche (public) Klassenfunktion eine entsprechende
> C-Funktion deklariert werden; zusätzlich müssen mindestens je ein Konstruktor
> und ein Destruktor deklariert werden (egal ob in der Klasse explizit
vorhanden
> oder nicht). Die Headerdatei muß so geschrieben werden, daß sie sowohl vom
C++
> als auch vom C-Compiler gelesen werden kann. Am Beispiel der Klasse Foo
ergibt
> sich dann die C-Headerdatei FooC.h:
>
> /* FooC.h : C interface to class Foo */
>
> #ifdef __cplusplus
> extern "C" {
> #endif
>
> typedef struct fooC FooC;
>
> extern FooC *FooCNew(int i, double d); /* Konstruktor */
> extern void FooCDelete(FooC *Obj); /* Destruktor */
>
> extern int FooCGetInt(FooC *Obj);
> extern double FooCGetDouble(FooC *Obj);
>
> #ifdef __cplusplus
> }
> #endif
>
>
> 3. Konstruktion der C-Implementierung
> ======================================
> Die C-Implementierung des Interfaces muß so erfolgen, daß sie von dem C++
> Compiler übersetzt werden kann. Jede Funktion wird umgesetzt in einen Aufruf
> der entsprechenden Klassenfunktion. Daraus ergibt sich dann am Beispiel der
> Klasse Foo die C-Sourcedatei FooC.c:
>
> /* FooC.c */
>
> #include "Foo.h" // C++ Klasseninterface
> #include "FooC.h" // C Klasseninterface
>
> FooC *FooCNew (int i, double d) // Konstruktor
> {
> Foo *aFoo = new Foo(i,d);
> return (FooC *)aFoo;
> }
>
> void FooCDelete (FooC *Obj) // Destruktor
> {
> Foo *aFoo = (Foo *)Obj;
> delete aFoo;
> }
>
> int FooCGetInt(FooC *Obj)
> {
> Foo *aFoo = (Foo *)Obj;
> return aFoo->getInt();
> }
>
> double FooCGetDouble(FooC *Obj)
> {
> Foo *aFoo = (Foo *)Obj;
> return aFoo->getDouble();
> }
>
>
> Diese Sourcedatei wird jetzt zusammen mit der C++ Sourcedatei kompiliert und
> in die Bibliothek eingebunden.
>
>
> 4. Benutzung der Klassenbibliothek
> ==================================
> Die so an C angepasste Klassenbibliothek kann jetzt sowohl aus C++ Code als
> auch aus C-Code heraus verwendet werden. Die C++ Sourcedatei zieht dabei die
> C++ Headerdatei an, während die C Sourcedatei die C-Headerdatei anzieht.
>
> 4.1 Benutzung des C++ Interfaces
> ---------------------------------
> Am Beispiel der C++ Sourcedatei useFoo.c wird zunächst gezeigt, wie die
> Klasse Foo normalerweise in C++ Code verwendet wird:
>
> // useFoo.c
>
> #include <iostream.h>
> #include "Foo.h" // include C++ interface
>
> int main()
> {
> Foo myFoo(2, 1.4142);
> cerr << "myFoo: " << myFoo.getInt() <<'/' << myFoo.getDouble() << endl;
>
> return 0;
> }
>
>
> 4.2 Benutzung des C Interfaces
> -------------------------------
> Die Verwendung der Klassenbibliothek in C sieht man parallel dazu in der
> Sourcedatei useFooC.c:
>
> /* useFooC.c */
>
> #include <stdio.h>
> #include "FooC.h" /* include C interface */
>
> int main()
> {
> FooC *myFooC = FooCNew(2, 1.4142);
> (void)printf("myFooC: %d/%f\n", FooCGetInt(myFooC), FooCGetDouble(myFooC));
> FooCDelete(myFooC);
>
> return 0;
> }
>
>
> Im Gegensatz zum C++ Code, wo die Objekte durch impliziten Aufruf ihres
> Destruktors automatisch entfernt werden, muß dies im C-Code explizit erfolgen
> und darf nicht vergessen werden! Andernfalls wird der verwendete Speicher
> nicht freigegeben und ist durch den Zeiger myFoo auch nicht mehr zugänglich,
> nachdem dieser vom Stack abgeräumt wurde.
>-- End of excerpt from Andreas Huennebeck

-- 
------------------------
Alexej Jerschow

present address:

MR-Center, SINTEF UNIMED N-7034 Trondheim, Norway Tel: +47-73 99 89 36 Fax: +47-73 99 77 08