Man, IBM’s XL C compiler doesn’t seem to like Progress.
I got this as factorial.p
procedure factorial external "/home/sauge/c/factorial.so" cdecl :
define input parameter n as short.
define return parameter f as short.
end. /* shared library */
define variable Result as integer no-undo.
run factorial (4, output Result).
disp Result. /* should be 4 * 3 * 2 * 1 */
and my factorial is this:
int factorial(int n)
{
if (n == 0) return 1;
return n * factorial(n - 1);
}
And compiled that into /home/sauge/c/factorial.so.
My pro is this:
#!/bin/bash
export LIBPATH=/home/sauge/c
/var/dlc/bin/pro
The LIBPATH and absolute path in the procedure should say use /home/sauge/c/factorial.so right?
Ran my ./pro and got this:
So after a WTF I wrote a runner that will load in the .so and run the program from there like Progress should. Here is run.c:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
int (*factorial)(int);
char *error;
handle = dlopen ("/home/sauge/c/factorial.so", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
factorial = (int(*)(int)) dlsym(handle, "factorial");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
printf ("Factorial is %d\n", (*factorial)(4));
dlclose(handle);
}
And ran it:
:c $ ./run
Factorial is 24
Works.
So… Grrrrrr
All I can think is that Progress is linked with a different version of a dynamic link loader library and is confused???
Here are the build instructions:
:c $ cat makefile
all: factorial.c
cc -c factorial.c
cc -bE:factorial.exp -bM:SRE -bnoentry -o factorial.so factorial.o
run: run.c
cc -o run run.c -L:/home/sauge/c factorial.so -bnoquiet
and the symbols
:c $ cat factorial.exp
factorial
Anyone spot what is going on?
Just for kicks, does your new exe have the same permissions/ownership as $DLC/bin/_progres? _progres is owned by root, typically, and has setuid permission. This affects the dynamic loader on various platforms. IIRC, some platforms will only load from /usr/lib under those circumstances, ignoring the library path env var. That might be worth taking a look at.
Found the problem - XL C for AIX defaults to compiling to 32bit and _progres is compiled as 64 bit. Duh.
Changed the makefile to:
all: factorial.c
xlc -q64 -c factorial.c
xlc -q64 -qmkshrobj -o factorial.so factorial.o
run: run.c
xlc -q64 -o run run.c -L:/home/sauge/c factorial.so
clear:
rm run factorial.o factorial.so
Also needed to add the directory /home/sauge/c with the .so in PROLIBPATH. If you put the .so where it belongs, it works without modification but I don't have root permission. :)
After doing so, the C and Progress ABL code behave.