For Programmers: Free Programming Magazines  


Home > Archive > Fortran > December 2004 > Again - Mixed language programming Tcl/Tk and Fortran (Windows)









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Again - Mixed language programming Tcl/Tk and Fortran (Windows)
Gustav Ivanovic

2004-12-22, 9:13 pm

Two parts:
1. Tcl code
2. Fortran code. Compile this with CFV to make a dll.
in the example it is called FtnTcl.dll

Be careful with truncated lines.

Have fun !

PART 1 Tcl

########################################
##############
namespace eval Fortran {

########################################
#########
# Provides simplified call to CV Fortran DLL for strings and
arrays
# Works with Compaq Visual Fortran 6.1A
# See also "Programming with Mixed Languages" chapter in CVF
Reference Manual
# ffidl can be found here http://www.elf.org/ffidl/
########################################
#########

proc DirectCall {DLLname routineName varType var} {
# varType is a, i, f or d
# a means CHARACTER(LEN=*) in Compaq Visual Fortran
# f means REAL, DIMENSION(*) in Compaq Visual Fortran
# d means DOUBLE PRECISION, DIMENSION(*) in Compaq Visual
Fortran
# i means INTEGER, DIMENSION(*) in Compaq Visual Fortran,
#
# array size shall be defined as argument in fortran
# see fortran source code
#

upvar $var x
if {$varType == "a"} {
eval [subst {ffidl::callout TclCallName {pointer-var int}
void [ffidl::symbol $DLLname $routineName]}]
set x [binary format a* $x]
TclCallName x [string length $x]
binary scan $x a* x
} else {
eval [subst {ffidl::callout TclCallName {pointer-var} void
[ffidl::symbol $DLLname $routineName]}]
set formatString $varType[llength $x]
set x [binary format $formatString $x]
TclCallName x
binary scan $x $formatString x
}
};#End proc DirectCall

proc DefineCallout {DLLname routineName argDef returnDef} {
# The callout will be inside Fortran namespace ( e.g
Fortran::scalarproduct )
eval [subst {ffidl::callout ::Fortran::$routineName {$argDef}
$returnDef [ffidl::symbol $DLLname $routineName]}]
};#End proc DefineCallout

proc binarize {varType args} {
foreach var $args {
upvar $var x
if {$varType == "a"} {
set x [binary format a* $x]
} else {
set x [binary format $varType[llength $x] $x]
}
}
};#End proc binarize

proc de-binarize {varType args} {
foreach var $args {

upvar $var x
switch $varType {
i {binary scan $x i[expr {[string length $x]/4}] x}
f {binary scan $x f[expr {[string length $x]/4}] x}
d {binary scan $x d[expr {[string length $x]/8}] x}
default {binary scan a* $x x}
}
}
};#End proc de-binarize


};#End namespace Fortran


proc runTest {} {

# Example starts here
load ffidl05.dll

# Call routines using Fortran::DirectCall
# Example with strings
puts "Test 1"
set line ABCDE***
puts $line
Fortran::DirectCall FtnTcl.dll string a line
puts $line

# Example with integers
puts "Test 2"
set x {1 2 3 4}
puts $x
Fortran::DirectCall FtnTcl.dll integervector i x
puts $x

# Example with floating points
puts "Test 3"

set x {1 2 3 4}
puts $x
Fortran::DirectCall FtnTcl.dll realvector f x
puts $x

# Example with double precisions
puts "Test 4"
set x {1 2 3 4}
puts $x
Fortran::DirectCall FtnTcl.dll doublevector d x
puts $x

# Define Callout using Fortran::DefineCallout and then call the
routine
puts "Test 5"
Fortran::DefineCallout FtnTcl.dll scalarproduct {pointer-var
pointer-var pointer-var} float

set l 4
set x {1 1 1 1}
set y {2 2 2 2}
Fortran::binarize i l
Fortran::binarize f x y
puts [Fortran::scalarproduct x y l]

puts "Test 6"
set x {1 2 3 4}
set y {0 0 0 0}
Fortran::binarize f x y
puts [Fortran::scalarproduct x y l]

# More examples
# define the callout using ffidl
puts "More examples"
ffidl::callout scalarProduct {pointer-var pointer-var pointer-var}
float [ffidl::symbol FtnTcl.dll scalarproduct]
ffidl::callout doubleVectorSum {pointer-var pointer-var
pointer-var pointer-var} float [ffidl::symbol FtnTcl.dll
doublevectorsum]

set x {1 2 3 4}
set y {1 2 3 4}
set l 4
Fortran::binarize f x y
Fortran::binarize i l
puts [scalarProduct x y l]

set y {10 10 10 10}
Fortran::binarize f y
puts [scalarProduct x y l]

set x {1 2 3 4}
set y {10 10 10 10}
set z $x
Fortran::binarize d x y z
doubleVectorSum x y z l
Fortran::de-binarize d x y z
puts $x
puts $y
puts $z
};#Endproc runTest

###########
#EXECUTE IT
###########
runTest
########################################
##############


PART 2 Fortran

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!
MODULE tcl


CONTAINS


SUBROUTINE doublevector(vector)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'doublevector' ::doublevector
DOUBLE PRECISION , DIMENSION(*) :: vector
vector(3)=3333.
END SUBROUTINE doublevector

SUBROUTINE realvector(vector)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'realvector' ::realvector
REAL , DIMENSION(*) :: vector
vector(2)=2222.
END SUBROUTINE realvector


SUBROUTINE integervector(vector)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'integervector' ::integervector
INTEGER , DIMENSION(*) :: vector
vector(1)=1111
END SUBROUTINE integervector


SUBROUTINE string(line)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'string'::string
CHARACTER(LEN=*) :: line
line='QWERTY'
END SUBROUTINE string

FUNCTION scalarproduct(x,y,n) RESULT (z)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'scalarproduct'::scalarproduct
INTEGER ::n
REAL, DIMENSION(n) :: x, y
REAL :: z
z=sum(x*y)
END FUNCTION scalarproduct

SUBROUTINE doublevectorsum(x,y,z,n)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:
'doublevectorsum'::doublevectorsum
INTEGER ::n
DOUBLE PRECISION, DIMENSION(n) :: x, y, z
z=x+y
END SUBROUTINE doublevectorsum

END MODULE tcl
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!
Arjen Markus

2004-12-23, 9:03 am

Gustav Ivanovic wrote:
>
> Two parts:
> 1. Tcl code
> 2. Fortran code. Compile this with CFV to make a dll.
> in the example it is called FtnTcl.dll
>
> Be careful with truncated lines.
>
> Have fun !
>


This is cute.

Do you know my "Ftcl" library? (It is available on
the Internet at various places)

The philosophy there is to have a Fortran program
that can use a Tcl interpreter - it tries to make
the interface as transparant as possible.

But, I must say, this looks like a nice solution too :)

Regards.

Arjen
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com