external rexx function dll with cygwin gcc ?
Author |
Message |
Gottfried Hegmann #1 / 6
|
 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 |
|
 |
Mark Yudki #2 / 6
|
 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 |
|
 |
Gottfried Hegmann #3 / 6
|
 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 |
|
 |
Mark Yudki #4 / 6
|
 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); > }
/*-------------------------------------------------------------------------- --*/ 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 */ > /* */
/*-------------------------------------------------------------------------- --*/ 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 |
|
 |
hessling mar #5 / 6
|
 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 |
|
 |
Mark Yudki #6 / 6
|
 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/ 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 |
|
|
|