external rexx function dll with cygwin gcc ? 
Author Message
 external rexx function dll with cygwin gcc ?

Is anyone out there who made it to create a rexx external function dll
for windows using the cygwin gcc cmpiler ? I've got it compiled and
linked but it immediately traps upon the first call to a function in
that dll with the following pop-up:

The instruction at "0x00018084" referenced memory at "0x00018084". The
memory could not be "read".

Gottfried Hegmanns



Mon, 16 Feb 2004 21:58:09 GMT  
 external rexx function dll with cygwin gcc ?
Sounds like a calling convention mixup.
I was unable to get the GNU C/C++ for OS/2 to generate exactly compatible
calling conventions. I suspect., however, that CygWin is not so poor, but
you're going to have to stare at the documentation on calling conventions to
get it right.


Quote:
> Is anyone out there who made it to create a rexx external function dll
> for windows using the cygwin gcc cmpiler ? I've got it compiled and
> linked but it immediately traps upon the first call to a function in
> that dll with the following pop-up:

> The instruction at "0x00018084" referenced memory at "0x00018084". The
> memory could not be "read".

> Gottfried Hegmanns



Tue, 17 Feb 2004 13:38:29 GMT  
 external rexx function dll with cygwin gcc ?

Quote:
> Here's how it works under OS/2 (emx+gcc):

You need three files, hello.c and helloos2.def. Cut these from between the '=='
lines, then
run the command, then test it with testhello.cmd

================ hello.c ======================
#include <stdlib.h>
#include <stdio.h>
#include <os2emx.h>
#define PVERSION "0.0"
#define OK 0
#define INVALID_CALL 40

/*----------------------------------------------------------------------------*/

/* This routine returns a string 'Hello world: ' plus the first argument      */

/*                                                                            */

/*----------------------------------------------------------------------------*/

ULONG helloWorld(PCSZ name, LONG argc, const RXSTRING *argv,
                    PCSZ queuename, PRXSTRING retstr)
{
  char *argv0;
  retstr->strlength = 0;
  if (argc != 1) return(INVALID_CALL);
  strcpy(retstr->strptr, "Hello world: ");
  argv0 = RXSTRPTR(argv[0]);
  strcat(retstr->strptr, argv0);
  retstr->strlength = strlen(retstr->strptr);
  return(OK);

Quote:
}

/*----------------------------------------------------------------------------*/

/* Routines to register these functions                                       */

/*                                                                            */

/* Returns the version of this program.                                       */

/* If one parameter is given, it prints out the version string.               */

/* Calling this function with more than one parameter causes "Incorrect call  */

/* to routine".                                                               */

/*----------------------------------------------------------------------------*/

static void regfun (PCSZ name)
{
  RexxRegisterFunctionDll (name, "HELLOOS2", name);

Quote:
}

/*----------------------------------------------------------------------------*/

/* This function will register all other functions                            */

/*                                                                            */

/*----------------------------------------------------------------------------*/

ULONG helloLoadFuncs (PCSZ name, LONG argc, const RXSTRING *argv,
                        PCSZ queuename, PRXSTRING retstr)
{
  int rc;
  char *vs = PVERSION;
  if (argc > 1) return INVALID_CALL;
  regfun("helloWorld");
  printf("helloLoadFuncs: helloos2.dll Library loaded\n");
  MAKERXSTRING(*retstr, vs, strlen(vs));
  return(OK);

Quote:
}

===================================================
============ helloos2.def =========================
LIBRARY HELLOOS2 INITINSTANCE
DESCRIPTION 'test rexx external function dll with gcc+emx under OS/2'
DATA
   MULTIPLE NONSHARED
EXPORTS
  HELLOWORLD             = helloWorld
  HELLOLOADFUNCS         = helloLoadFuncs
===================================================
=============== the command =======================
gcc -Zmap -Zdll -Zomf -Zso -Zsys -Zlinker /map -s -O  \
                  -o helloos2.dll hello.c helloos2.def
===================================================
============= testhello.cmd ==========================
/**/
call RxFuncAdd 'helloLoadFuncs', "helloos2", 'helloLoadFuncs'
xx = helloLoadFuncs(1)
say 'library version <'xx'> sucessfully loaded'
answer = helloWorld("*** This is an argument ***")
say answer
===================================================


Tue, 17 Feb 2004 19:39:07 GMT  
 external rexx function dll with cygwin gcc ?
I'll give your magic gcc options a try. But IIRC, my problems came with
structs that weren't being passed identically.


Quote:
> > Here's how it works under OS/2 (emx+gcc):

> You need three files, hello.c and helloos2.def. Cut these from between the
'=='
> lines, then
> run the command, then test it with testhello.cmd

> ================ hello.c ======================
> #include <stdlib.h>
> #include <stdio.h>
> #include <os2emx.h>
> #define PVERSION "0.0"
> #define OK 0
> #define INVALID_CALL 40

/*--------------------------------------------------------------------------
--*/
Quote:

> /* This routine returns a string 'Hello world: ' plus the first argument
*/

> /*
*/

/*--------------------------------------------------------------------------
--*/
Quote:

> ULONG helloWorld(PCSZ name, LONG argc, const RXSTRING *argv,
>                     PCSZ queuename, PRXSTRING retstr)
> {
>   char *argv0;
>   retstr->strlength = 0;
>   if (argc != 1) return(INVALID_CALL);
>   strcpy(retstr->strptr, "Hello world: ");
>   argv0 = RXSTRPTR(argv[0]);
>   strcat(retstr->strptr, argv0);
>   retstr->strlength = strlen(retstr->strptr);
>   return(OK);
> }

/*--------------------------------------------------------------------------
--*/

- Show quoted text -

Quote:

> /* Routines to register these functions
*/

> /*
*/

> /* Returns the version of this program.
*/

> /* If one parameter is given, it prints out the version string.
*/

> /* Calling this function with more than one parameter causes "Incorrect
call  */

> /* to routine".
*/

/*--------------------------------------------------------------------------
--*/
Quote:

> static void regfun (PCSZ name)
> {
>   RexxRegisterFunctionDll (name, "HELLOOS2", name);
> }

/*--------------------------------------------------------------------------
--*/
Quote:

> /* This function will register all other functions
*/

> /*
*/

/*--------------------------------------------------------------------------
--*/

- Show quoted text -

Quote:

> ULONG helloLoadFuncs (PCSZ name, LONG argc, const RXSTRING *argv,
>                         PCSZ queuename, PRXSTRING retstr)
> {
>   int rc;
>   char *vs = PVERSION;
>   if (argc > 1) return INVALID_CALL;
>   regfun("helloWorld");
>   printf("helloLoadFuncs: helloos2.dll Library loaded\n");
>   MAKERXSTRING(*retstr, vs, strlen(vs));
>   return(OK);
> }
> ===================================================
> ============ helloos2.def =========================
> LIBRARY HELLOOS2 INITINSTANCE
> DESCRIPTION 'test rexx external function dll with gcc+emx under OS/2'
> DATA
>    MULTIPLE NONSHARED
> EXPORTS
>   HELLOWORLD             = helloWorld
>   HELLOLOADFUNCS         = helloLoadFuncs
> ===================================================
> =============== the command =======================
> gcc -Zmap -Zdll -Zomf -Zso -Zsys -Zlinker /map -s -O  \
>                   -o helloos2.dll hello.c helloos2.def
> ===================================================
> ============= testhello.cmd ==========================
> /**/
> call RxFuncAdd 'helloLoadFuncs', "helloos2", 'helloLoadFuncs'
> xx = helloLoadFuncs(1)
> say 'library version <'xx'> sucessfully loaded'
> answer = helloWorld("*** This is an argument ***")
> say answer
> ===================================================



Thu, 19 Feb 2004 15:29:09 GMT  
 external rexx function dll with cygwin gcc ?
:> Here's how it works under OS/2 (emx+gcc):
[code snipped]
Gottfried,

There is a problem in your code that causes Regina to crash. The line:
  MAKERXSTRING(*retstr, vs, strlen(vs));
in helloLoadFuncs() should be replaced with the following two lines:
  strcpy( retstr->strptr, vs);
  retstr->strlength = strlen(vs);

The reason is that by default Regina provides a 256 character RXSTRING in which
you can deposit your return code from the external function. If you need to return
a value longer than 256 characters, you must allocate an RXSTRING strptr of suitable
length and populate the allocated memory.

When the external function returns to Regina, it checks to see if the address of the
pointer supplied to the external function is the same as the one coming back. If not,
it assumes that the memory has been allocated and free's it.

In your code, the pointers are different, but the memory you are passing back is a
constant, and when Regina tries to free it; it crashes.
The OS/2 Rexx manual should explain this requirement (the Object Rexx one does, and I
hope the Regina manual also does).

I guess that the reason it works under OS/2 is that freeing up a constant memory address
may not cause problems until later in the execution of the code (and you may get away with
it forever!)

Cheers, Mark
---------------------------------------------------------------------------

* Author of THE; a Free XEDIT/KEDIT editor, Rexx/SQL, Rexx/Curses, Rexx/Wrapper
* Maintainer of PDCurses: Public Domain Curses and, Regina Rexx interpreter
* Use Rexx? join the Rexx Language Association: http://www.rexxla.org



Fri, 20 Feb 2004 11:35:57 GMT  
 external rexx function dll with cygwin gcc ?

Quote:
> I guess that the reason it works under OS/2 is that freeing up a constant
memory address
> may not cause problems until later in the execution of the code (and you
may get away with
> it forever!)

Actually, the same applies to IBM REXX on OS/2 too, and the program may well
crash.


Quote:

> :> Here's how it works under OS/2 (emx+gcc):
> [code snipped]
> Gottfried,

> There is a problem in your code that causes Regina to crash. The line:
>   MAKERXSTRING(*retstr, vs, strlen(vs));
> in helloLoadFuncs() should be replaced with the following two lines:
>   strcpy( retstr->strptr, vs);
>   retstr->strlength = strlen(vs);

> The reason is that by default Regina provides a 256 character RXSTRING in
which
> you can deposit your return code from the external function. If you need
to return
> a value longer than 256 characters, you must allocate an RXSTRING strptr
of suitable
> length and populate the allocated memory.

> When the external function returns to Regina, it checks to see if the
address of the
> pointer supplied to the external function is the same as the one coming
back. If not,
> it assumes that the memory has been allocated and free's it.

> In your code, the pointers are different, but the memory you are passing
back is a
> constant, and when Regina tries to free it; it crashes.
> The OS/2 Rexx manual should explain this requirement (the Object Rexx one
does, and I
> hope the Regina manual also does).

> I guess that the reason it works under OS/2 is that freeing up a constant
memory address
> may not cause problems until later in the execution of the code (and you
may get away with
> it forever!)

> Cheers, Mark
> --------------------------------------------------------------------------
-


http://www.lightlink.com/hessling/

- Show quoted text -

Quote:
> * Author of THE; a Free XEDIT/KEDIT editor, Rexx/SQL, Rexx/Curses,
Rexx/Wrapper
> * Maintainer of PDCurses: Public Domain Curses and, Regina Rexx
interpreter
> * Use Rexx? join the Rexx Language Association: http://www.rexxla.org



Sun, 22 Feb 2004 14:14:17 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Making Rexx Function DLL's with emx/gcc

2. Rexx external function DLLs

3. External Rexx DLL in C and VX-REXX

4. Passing REXX stems to external REXX functions -Reply

5. Passing REXX stems to external REXX functions

6. sharing external functions between cms rexx programs and xedit rexx programs

7. external rexx function calls (OS/2 REXX)

8. MVS-REXX: Howto write REXX external functions in C

9. OS/2 REXX DLLS with EMX/GCC compiler?

10. rexx calls to external dlls on NT

11. VX-REXX and external DLL's

12. Calling an non-DLL external function

 

 
Powered by phpBB® Forum Software