Glenn Howes wrote:
I have a legacy static library written in Pascal which I need to call from a C++ application targeting both PowerPC and x86 processors on the Mac OS X platform ( a so-called universal binary). After compiling and linking everything together, I'm having trouble calling the Pascal runtime libraries: i.e. I crash.
Software used:
glenn% gpc -v Reading specs from /Developer/Pascal/gpc345u2/lib/gcc/powerpc-apple-darwin8/3.4.5/specs Configured with: ../gcc-3.4.5/configure --enable-languages=pascal,c --enable-threads=posix --target=powerpc-apple-darwin8 --host=powerpc-apple-darwin8 --build=powerpc-apple-darwin8 --prefix=/Developer/Pascal/gpc345u2 Thread model: posix gpc version 20051116, based on gcc-3.4.5
gpc-i386 -vReading specs from /Developer/Pascal/gpc345u2/lib/gcc/i386-apple-darwin8/3.4.5/specs Configured with: ../gcc-3.4.5/configure --enable-languages=pascal,c --enable-threads=posix --target=i386-apple-darwin8 --host=powerpc-apple-darwin8 --build=powerpc-apple-darwin8 --prefix=/Developer/Pascal/gpc345u2 --with-sysroot=/Developer/SDKs/MacOSX10.4u.sdk/ --with-arch=pentium-m --with-tune=prescott Thread model: posix gpc version 20051116, based on gcc-3.4.5
Mac OS X 10.4.4 XCode 2.2.1
Source: 34 files of legacy Pascal which I've gone through and fixed all of the compiler errorss and most of the warnings.
Steps I've taken.
- Compiled and packaged using gpc, libtool, and lipo:
gpc -c --automake -Wl,-framework,Carbon -funit-path=/Developer/Pascal/GPCPInterfaces/ MySrc.p libtool -static *.o -o MyLibPPC.a rm *.gpi rm *.o gpc-i386 -c --automake -Wl,-framework,Carbon -funit-path=/Developer/Pascal/GPCPInterfaces/ MySrc.p libtool -static *.o -o MyLibx86.a
Sidebar - when linking a framework to i386 code on powerpc-darwin (Mac OS X), you generally have to add -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk/. In this specific case, the linker doesn't complain about it, because you are creating a static library.
lipo *.a -create -output MyLib.a
- Made a universal version of the gpc.a library
lipo /Developer/Pascal/gpc345u2/lib/gcc/i386-apple-darwin8/3.4.5/ libgpc.a /Developer/Pascal/gpc345u2/lib/gcc/powerpc-apple-darwin8/ 3.4.5/libgpc.a -create -output gpc.a
Added both libraries to my XCode 2.2.1 C++ application
Compile and Links without running, crashes as soon as it tries to
call WriteLn, if I remove the WriteLn, it crashes later in a call to the file routine Assign, which might be the first runtime library call.
I declare the entry in C++ as: extern "C" short MyEntry(const char *path);
In Pascal, I declare it as
const MaxPointerChars = 20000; Type PAPointerChar=^APointerChar; APointerChar = Packed Array [0..MaxPointerChars] of Char; Int16 = Integer attribute ( size = 16); ...
function MyEntry(DllPathC:PAPointerChar):Int16; attribute (name = 'MyEntry');
...
function MyEntry(aCString:PAPointerChar):Int16; var DLLPath:String2048; pathLength:Int32; i:Int32; begin pathLength := StrLen(aCString); if pathLength > 2048 then pathLength := 2048; DLLPath := ''; for i := 1 to pathLength do begin DLLPath := DLLPath + aCString^[i-1]; end; WriteLn(DLLPath); { crashes here}
...
gdb gives me the following console output: Running… Program received signal: "EXC_BAD_ACCESS".
Unable to disassemble _p_Write_Init.
What you have done is all fine (I am glad there are people who *do* read README files), except that you have to initialize the GPC runtime library, see /Developer/Pascal/gpc345u2/doc/gpc/demos/gpc_c_c.c and the gpc mailing list archive at http://www.gnu-pascal.de/crystal/gpc/en/.
- I've written a little test application in Pascal to debug the
libraries code (when it is not packaged as a library but compiled directly into the application) and the code works perfectly well in that environment. The debugging was done with XCode 2.1 as I believe there is a problem with gpc and XCode 2.2.
Oh, there is a workaround for the bug in Xcode 2.2 and Xcode 2.2.1, see recent postings in the macpascal mailing list archive at http://www.pascal-central.com/archives.html.
Regards,
Adriaan van Os