System: Windows 95/98/NT
Languages: S+ version 4.x or S+ 2000
Compilers: Watcom c/c++ 11.0 Watcom Fortran 11.0
Problems:
1) It is impossible to print to S+ from Fortran
2) It is impossible to print to a stream output object from C++
3) In ordinary mixed language programming between Fortran and C,
the output from Fortran and C/C++ are stored in seperate buffers,
so the output is not printed in the correct order
4) The functions, S_alloc and newio_printf, in SQPE.dll can not be
reliably called from dlls. Strangely, these functions work fine on
486 and earlier procesors, but they have caused GPF's when I called
them on Pentium based systems.
5) The stack used by the Fortran output routines, __ASTACKPTR, is
not initialized correctly, when dllmain is defined in an object module
of a mixed language Dll
6) __ASTACKPTR is incompatible with __CHK in splus, and causes a GPF.
Solution:
I have written a set of Dll's and S functions which replace part of the
output library of the Watcom Fortran compiler. I have written a module which
coordinates the output between C/C++ and Fortran. I have written a C++ stream
object which prints to the S+ output screen. Attached are two files:
readme.txt and splibdoc.txt which document the programs. I will be posting
the zip files on the WEB somewhere soon, untill then you can write me
at ClarkSimssplus@my-deja.com if you want a copy of the zip files.
!!! Important Note: Sybase will discontinue the Watcom Fortran/C/C++
!!! compilers as of August 31, 1999, so be sure to buy a copy if you
!!! you want to compile this code (the dyn.load command works only
!!! with WATCOM object files, and the dyn.load statement is necessary
!!! to this installation). I will work on a similar installation
!!! for Microsoft, Boreland and GNU, but this is all I have for now.
!!! The future releases will still use object files compiled with
!!! WATCOM for the dyn.load statements.
--== Sent via Deja.com http://www.deja.com/ ==--
Share what you know. Learn what you don't. !!! Important Note: Sybase will discontinue the Watcom Fortran/C/C++
!!! compilers as of August 31, 1999, so be sure to buy a copy if you
!!! you want to compile this code (the dyn.load command works only
!!! with WATCOM object files, and the dyn.load statement is necessary
!!! to this installation) !!!!
Instructions for installation
Step 1) Unzip the files
go to the library subdirectory under S_HOME,
(Typically c:\progra~1\splus45\library or c:\progra~1\sp2000\library)
create the 3 subdirectories with the dos commands:
md cclib
md cclib\_data
md cclib\_data\_help
The full path should look something like:
c:\progra~1\splus45\library\cclib
c:\progra~1\splus45\library\cclib\_data
c:\progra~1\splus45\library\cclib\_data\_help
or
c:\progra~1\sp2000\library\cclib
c:\progra~1\sp2000\library\cclib\_data
c:\progra~1\sp2000\library\cclib\_data\_help
go to the cclib directory under S_HOME and unzip splus.zip,
the Pkzip the command is: pkunzip (path)\splus.zip
where path is the location of splus.zip
If you use Winzip you must use the windows dialog boxes to unzip cclib.txt and
heap.txt to $(S_HOME)\library\cclib
choose a place for a new subdirectory cclib, typically C:
You will unzip cclib.zip to this place.
Note that the directory structure is stored in the zip file, so
you do not have to create any directories by hand.
The Pkzip command is:
pkunzip -d (path)\cclib.zip
where path is the location of cclib.zip
The -d, option tells pkunzip to recreate the subdirectory structure.
If you use Winzip, you must use the windows dialog boxes to unzip cclib.zip.
Winzip should automaticly create the appropriate subdirectory structure.
Step 2) edit the environment table
If you use NT, call up the system editor, and edit the environment
The commands to do this are:
ctrl-escape
Settings
Control Panel
System
Environment
declare a variable cclib and set it equal to the position of the correct
subdirectory, for example
CCLIB=C:\CCLIB
add %CCLIB%\LIBNT to the LIB variable, for example:
LIB=C:\WATCOM\lib386\nt;%cclib%\libnt
add %cclib%\h to the include variable, for example:
INCLUDE=C:\WATCOM\H;C:\WATCOM\H\NT;C:\SPLUS45\INCLUDE;%cclib%\h
add %cclib%\libnt to the path, for example:
PATH=(lots of stuff);%cclib%\libnt
If you which to use the WATCOM source level debugger with the source files
in this install, you must also add the subdirectories containing the source
files. For example
PATH=(lots of
stuff);%cclib%\libnt;%cclib%\event;%cclib%\dlist;%cclib%\math;%cclib%\splus
After you have made these changes, you are ready to procede. It is not
necessary to reboot. However, all DOS boxes which are open,
must be closed and reopened, in order for the new environment variables
to take effect.
If you use Windows 95 or 98, you must edit the environment variables in
the autoexec.bat file on the boot drive.
declare a variable cclib and set it equal to the position of the correct
subdirectory, for example
SET CCLIB=C:\CCLIB
add %CCLIB%\LIBNT to the LIB variable, for example:
SET LIB=C:\WATCOM\lib386\nt;%cclib%\libnt
add %cclib%\h to the include variable, for example:
SET INCLUDE=C:\WATCOM\H;C:\WATCOM\H\NT;C:\SPLUS45\INCLUDE;%cclib%\h
add %cclib%\libnt to the path, for example:
PATH=(lots of stuff);%cclib%\libnt
or if you don't have the full path declared in your autoexec.bat file,
PATH=%PATH%;%cclib%\libnt
If you which to use the WATCOM source level debugger with the source files
in this install, you must also add the subdirectories containing the source
files. For example
PATH=(lots of
stuff);%cclib%\libnt;%cclib%\event;%cclib%\dlist;%cclib%\math;%cclib%\splus
or if you don't have the full path declared in your autoexec.bat file,
PATH=%PATH%;%cclib%\libnt
After you have made these changes, you must reboot.
Step 3) Compile the Dll's
Open up a dos prompt.
Goto the $(cclib) directory.
If you are not interested in the Fortran interface, then open the makewat.bat
file and rem out lines 101 and 102. They are preceded by the remark:
"rem This makes the sample Fortran dll"
at the command line prompt type: makewat targetonly.
The batchfile should compile all the necessary Dll's.
At the end, the message:EVERY THING COMPILED CORRECTLY
should appear. If it does not contact me at clarksimssplus@my-deja.com
If you want to clean up the directories, by deleting the object files
then at the command line promt type: makewat clean
Step 4) Load the Splus code
Start S+ (Splus 4.x or splus 2000)
at the S+ command line, type the following:
source( paste( getenv( "S_HOME"), "library\\cclib\\cclib.txt", sep="\\"))
source( paste( getenv( "S_HOME"), "library\\cclib\\heap.txt", sep="\\"))
Step 5)
Test the S+/C/C++ interface
# connect to the library
library( cclib)
# initialize the library
load.cclib()
# call tsthp1, this test the memory manager
tsthp1()
#the final output should look like:
j = 999
memavail = dfc8
fragmented_memory = cf8
num_used = 129
num_free = 27
memavail = ff10
fragmented_memory = 0
num_used = 2
num_free = 0
>
# call the heap and show what is being used
global.heap.write.last.used()
# note that the allocations come from the fortran/C/C++ output manager
#load cpphello
#Note that the default calling convention is c_decl
#I normally would not ever use cdecl because in my experience
#it has been less stable than stdcall, but it makes no difference
#here because no arguments are being passed
load.cclib.dll( "cpphello.dll", c( "cpp_hello", "c_hello"), "cdecl")
#call chello, this demonstrates, eprintf, the "safe" way of
#calling newio_printf
.C( "c_hello")
# call cpphello, this demonstrates C++ stream output to Sostr
.C( "cpp_hello")
# call Fhello, this demonstrates Fortran Output
# note that FHELLO is ANSI standard code, so it does not
# call _FLUSH_SP
load.cclib.dll( "fhello.dll", c( "FHELLO", "FHELLO2"), "cdecl")
.Fortran( "FHELLO")
# must flush fortran output
.C( "_FLUSH_SP")
# call Fhello2, this demonstrates Fortran Output
# This function calls _FLUSH_SP from fortran
.Fortran( "FHELLO2")
# call FHELLO and then cpp_hello
# note that the FORTRAN output is automaticlly flushed before the C
.Fortran( "FHELLO")
.C( "cpp_hello")
6) For C / C++ functions use the source file %cclib%\splus\cpphello.cpp
as a template. To write ANSI code do either:
1) #define printf safe_printf
or
2) use the compiler flag -dprintf=safe_printf
Use the make file %cclib%\splus\wat1\cpphello.mak as a template.
You must be careful about the compile flags, which are defined in
%cclib%\wat1.inc\stackdll.inc
Stack based calling must be specified. Exception hadling must be enabled.
The following static libraries must be linked by the linker:
patchsq.lib
Dmyerror.lib
7) For Fortran programs use the source file %cclib%\splus\fhello.for as a
template.
To write ANSI code ommit references to _FLUSH_SP in the Fortran code,
and instead call it from Splus with the command .C( "_FLUSH_SP")
You must be careful about the compile flags, which are defined in
%cclib%\wat1.inc\stackdll.inc
Stack based calling must be specified.
The following static libraries must be EXPLICITLY linked in by the linker
(don't count on the linker to use Flib7s.lib!)
patchsq.lib
hacksp.lib
flib7s.lib
8) Refer to the documentation in SPLIBDOC.TXT when writing your own code.
9) Let me know what you think:
I would appreciate any feedback.
You can contact me at clarksimssplus@my-deja.com
Or you can post to the s-news mail group:
s-news@wubios.wustl.edu
Or you can post to the Sybase C/C++ group:
powersoft.public.watcom_c_c++.general
Or you can post to the Sybase Fortran group:
powersoft.public.watcom_fortran_77.general
Both of the Sybase groups are on the forums.sybase.com
news server.
|