gfxgfx
 
Please login or register.

Login with username, password and session length
 
gfx gfx
gfx
1617 Posts in 535 Topics by 779 Members - Latest Member: rhoronjeff@comcast.net November 27, 2022, 09:52:13 PM
*
gfx* Home | Help | Search | Login | Register | gfx
gfx
Absoft User Forum  |  Support  |  Windows  |  How to create a wrapper DLL for IMSL functions
gfx
gfxgfx
 

Author Topic: How to create a wrapper DLL for IMSL functions  (Read 13171 times)

alanray

  • Guest
How to create a wrapper DLL for IMSL functions
« on: October 20, 2007, 12:34:33 PM »
Hi All

I am new to this forum, but I have a topic which seems to not be covered adequately in the Absoft docs or forums.

I have to create a VB DLL which wraps an IMSL function.

That is apparently a very daunting task. At least I have not had success yet.

Unfortunately IMSL/VNI support is of NO help regarding Absoft-specific syntax, and can only provide me with a code example in Compaq Fortran 6, which is what I have modified.This is what I have so far. I have commented out the Compaq compiler instructions (!DEC$ ATTRIBUTES), etc.

I built the dll successfully, yet it does not work. When I execute my VB program it hangs, especially on the calls to Zreal.

The functions Call_ZREAL and Call_DZREAL expect a parameter named MYFCN which is an external function in Visual Basic. I dont know if I have properly declared that parameter, that must be one of my problems.

I continually see comments on the boards from people saying "that should be possible". Absoft support says that should be possible. IMSL support says that should be possible. Yet no robust fully fleshed out example seems to exist in the Absoft context. I believe solving this issue would be of benefit to the entire Absoft community.

Is there anyone who has enough expertise to see what I am doing wrong?
Thanks
Alan Young

code follows
===================================

Fortran Code


!!!!!!!!!!!!!!!!!!!!! START !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
stdcall   SUBROUTINE Call_LSARG(N, A, LDA, B, IPATH, X)
     !    !DEC$ ATTRIBUTES DLLEXPORT :: Call_LSARG
     !    !DEC$ ATTRIBUTES ALIAS:'Call_LSARG' :: Call_LSARG

   INTEGER,INTENT(IN) :: N
      REAL,INTENT(IN) :: A(N,N)
      INTEGER,INTENT(IN) :: LDA
      REAL,INTENT(IN) :: B(N)
   INTEGER,INTENT(IN) :: IPATH
      REAL,INTENT(OUT) :: X(N)

      Call LSARG (N, A, LDA, B, IPATH, X)

   END SUBROUTINE
! C     =====================================================

stdcall   SUBROUTINE Call_DLSARG(N, A, LDA, B, IPATH, X)
      !      !DEC$ ATTRIBUTES DLLEXPORT :: Call_DLSARG
      !     !DEC$ ATTRIBUTES ALIAS:'Call_DLSARG' :: Call_DLSARG

   INTEGER,INTENT(IN) :: N
      DOUBLE PRECISION,INTENT(IN) :: A(N,N)
      INTEGER,INTENT(IN) :: LDA
      DOUBLE PRECISION,INTENT(IN) :: B(N)
   INTEGER,INTENT(IN) :: IPATH
      DOUBLE PRECISION,INTENT(OUT) :: X(N)

      Call DLSARG (N, A, LDA, B, IPATH, X)

   END SUBROUTINE

! C     ========================================================

stdcall   SUBROUTINE Call_ZREAL(MYFCN, ERRABS, ERRREL, EPS, ETA, NROOT, ITMAX, XGUESS, X, INFO)
      !  !DEC$ ATTRIBUTES DLLEXPORT :: Call_ZREAL
      !  !DEC$ ATTRIBUTES ALIAS:'Call_ZREAL' :: Call_ZREAL

      REAL,INTENT(IN) :: ERRABS
      REAL,INTENT(IN) :: ERRREL
      REAL,INTENT(IN) :: EPS
      REAL,INTENT(IN) :: ETA
      INTEGER,INTENT(IN) :: NROOT
   INTEGER,INTENT(IN) :: ITMAX
      REAL,INTENT(IN) :: XGUESS(NROOT)
      REAL,INTENT(OUT) :: X(NROOT)
      INTEGER,INTENT(IN) :: INFO(NROOT)

      CALL ZREAL (MYFCN, ERRABS, ERRREL, EPS, ETA, NROOT, ITMAX, XGUESS, X, INFO)

   END SUBROUTINE

! C     ========================================================

stdcall   SUBROUTINE Call_DZREAL(MYFCN, ERRABS, ERRREL, EPS, ETA,NROOT, ITMAX, XGUESS, X, INFO)
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_DZREAL
      !   !DEC$ ATTRIBUTES ALIAS:'Call_DZREAL' :: Call_DZREAL

      DOUBLE PRECISION,INTENT(IN) :: ERRABS
      DOUBLE PRECISION,INTENT(IN) :: ERRREL
      DOUBLE PRECISION,INTENT(IN) :: EPS
      DOUBLE PRECISION,INTENT(IN) :: ETA
      INTEGER,INTENT(IN) :: NROOT
      INTEGER,INTENT(IN) :: ITMAX
      DOUBLE PRECISION,INTENT(IN) :: XGUESS(NROOT)
      DOUBLE PRECISION,INTENT(OUT) :: X(NROOT)
      INTEGER,INTENT(IN) :: INFO(NROOT)

      CALL DZREAL (MYFCN, ERRABS, ERRREL, EPS, ETA, NROOT, ITMAX,XGUESS, X, INFO)

   END SUBROUTINE

! C     ========================================================

stdcall   FUNCTION Call_NDAYS(IDAY, IMONTH, IYEAR)
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_NDAYS
      !   !DEC$ ATTRIBUTES ALIAS:'Call_NDAYS' :: Call_NDAYS

   INTEGER,INTENT(IN) :: IDAY
      INTEGER,INTENT(IN) :: IMONTH
   INTEGER,INTENT(IN) :: IYEAR

      Call_NDAYS = NDAYS (IDAY, IMONTH, IYEAR)

   return

   END FUNCTION

! C     ========================================================

stdcall   SUBROUTINE Call_ERSET(IERSVR, IPACT, ISACT)
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_ERSET
      !    !DEC$ ATTRIBUTES ALIAS:'Call_ERSET' :: Call_ERSET

   INTEGER,INTENT(IN) :: IERSVR
      INTEGER,INTENT(IN) :: IPACT
   INTEGER,INTENT(IN) :: ISACT

      Call ERSET (IERSVR, IPACT, ISACT)

   END SUBROUTINE

! C     ========================================================

stdcall   FUNCTION Call_IERCD()
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_IERCD
      !   !DEC$ ATTRIBUTES ALIAS:'Call_IERCD' :: Call_IERCD

      Call_IERCD = IERCD()

      return

   END FUNCTION

! C     ========================================================

stdcall   FUNCTION Call_N1RTY(ITYPE)
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_N1RTY
      !   !DEC$ ATTRIBUTES ALIAS:'Call_N1RTY' :: Call_N1RTY

   INTEGER,INTENT(IN) :: ITYPE
   
      Call_N1RTY = N1RTY (ITYPE)

      return

   END FUNCTION

! C     =====================================================

stdcall   SUBROUTINE Call_SGEMV(TRANS, M, N, SALPHA, SA, LDA, SX,INCX, SBETA, SY, INCY)
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_SGEMV
       !   !DEC$ ATTRIBUTES ALIAS:'Call_SGEMV' :: Call_SGEMV

   CHARACTER,INTENT(IN) :: TRANS
      INTEGER,INTENT(IN) :: M
      INTEGER,INTENT(IN) :: N
      REAL,INTENT(IN) :: SALPHA
   REAL,INTENT(IN) :: SA(LDA,N)
      INTEGER,INTENT(IN) :: LDA
   REAL,INTENT(IN) :: SX(M)
      INTEGER,INTENT(IN) :: INCX
      REAL,INTENT(IN) :: SBETA
      REAL,INTENT(IN) :: SY(M)
      INTEGER,INTENT(IN) :: INCY

      Call SGEMV(TRANS, M, N, SALPHA, SA, LDA, SX, INCX, SBETA, SY, INCY)

   END SUBROUTINE
   

========================================
VB Code  wrapper.bas

                                                                         
' Declare subroutines and functions in wrapper
Public Declare Sub Call_ERSET Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                   (IERSVR As Long, IPACT As Long, ISACT As Long)
Public Declare Function Call_IERCD Lib "c:\VB_F90\wrapper\debug\wrapper.dll" () As Long
Public Declare Function Call_N1RTY Lib "c:\VB_F90\wrapper\debug\wrapper.dll" (ITYPE As Long) As Long
Private Declare Sub Call_LSARG Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                    (N As Long, AA As Single, LDA As Long, _
                     BB As Single, IPATH As Long, XX As Single)
Private Declare Sub Call_DLSARG Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                    (N As Long, A As Double, LDA As Long, _
                     B As Double, IPATH As Long, X As Double)
Private Declare Sub Call_ZREAL Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                    (ByVal ZREAL_fcn As Long, ERRABS As Single, ERRREL As Single, _
                     EPS As Single, ETA As Single, NROOT As Long, ITMAX As Long, _
                     XGUESS As Single, X As Single, INFO As Long)
Private Declare Sub Call_DZREAL Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                    (ByVal ZREAL_fcn As Long, ERRABS As Double, ERRREL As Double, _
                     EPS As Double, ETA As Double, NROOT As Long, ITMAX As Long, _
                     XGUESS As Double, X As Single, INFO As Long)
Public Declare Function Call_NDAYS Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                        (IDAY As Long, IMONTH As Long, IYEAR As Long) As Long
Public Declare Sub Call_SGEMV Lib "c:\VB_F90\wrapper\debug\wrapper.dll" _
                   (ByVal TRANS As String, strLength As Long, M As Long, N As Long, SALPHA As Single, _
                    SA As Single, LDA As Long, SX As Single, INCX As Long, _
                    SBETA As Single, SY As Single, INCY As Long)

Sub DLSARG(N As Long, A As Double, LDA As Long, _
           B As Double, IPATH As Long, X As Double)

Call Call_DLSARG(N, A, LDA, B, IPATH, X)

End Sub

Sub ZREAL(ERRABS As Single, ERRREL As Single, EPS As Single, _
               ETA As Single, NROOT As Long, ITMAX As Long, XGUESS() As Single, _
               X() As Single, INFO() As Long)

Call Call_ZREAL(AddressOf ZREAL_fcn, ERRABS, ERRREL, EPS, ETA, NROOT, ITMAX, XGUESS(1), X(1), INFO(1))

End Sub

Function ZREAL_fcn(X As Single) As Single

' user supplied function for Call_ZREAL

ZREAL_fcn = X * X + 2 * X - 6

End Function

Function NDAYS(IDAY As Long, IMONTH As Long, IYEAR As Long) As Long

NDAYS = Call_NDAYS(IDAY, IMONTH, IYEAR)

End Function

Sub SGEMV(ByVal TRANS As String, M As Long, N As Long, SALPHA As Single, _
          SA As Single, LDA As Long, SX As Single, INCX As Long, _
          SBETA As Single, SY As Single, INCY As Long)

Dim strLength As Long

strLength = Len(TRANS)
         
Call Call_SGEMV(TRANS, strLength, M, N, SALPHA, SA, LDA, SX, INCX, SBETA, SY, INCY)

End Sub

==========================
vb code wrapper.frm
VERSION 5.00
Begin VB.Form Form1
   Caption         =   "Form1"
   ClientHeight    =   2070
   ClientLeft      =   2880
   ClientTop       =   2910
   ClientWidth     =   4545
   LinkTopic       =   "Form1"
   ScaleHeight     =   2070
   ScaleWidth      =   4545
   Begin VB.CommandButton SGEMV_BTN
      Caption         =   "Call SGEMV"
      BeginProperty Font
         Name            =   "MS Sans Serif"
         Size            =   8.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   615
      Left            =   2490
      TabIndex        =   3
      Top             =   330
      Width           =   1425
   End
   Begin VB.CommandButton DLSARG_BTN
      Caption         =   "Call DLSARG"
      BeginProperty Font
         Name            =   "MS Sans Serif"
         Size            =   8.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   615
      Left            =   540
      TabIndex        =   2
      Top             =   1080
      Width           =   1425
   End
   Begin VB.CommandButton QUIT_BTN
      Caption         =   "Quit"
      BeginProperty Font
         Name            =   "MS Sans Serif"
         Size            =   8.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   615
      Left            =   2490
      TabIndex        =   1
      Top             =   1080
      Width           =   1425
   End
   Begin VB.CommandButton ZREAL_BTN
      Caption         =   "Call ZREAL"
      BeginProperty Font
         Name            =   "MS Sans Serif"
         Size            =   8.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   615
      Left            =   540
      TabIndex        =   0
      Top             =   330
      Width           =   1425
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False

Private Sub DLSARG_BTN_Click()

Dim N As Long, LDA As Long, IPATH As Long
Dim Error_code As Long, Error_type As Long

' user input - Example from IMSL book
'==================
N = 3
LDA = 3
IPATH = 1

ReDim A(1 To LDA, 1 To LDA) As Double
ReDim B(N) As Double, X(N) As Double
ReDim Solution(N) As Double

A(1, 1) = 33
A(1, 2) = 16
A(1, 3) = 72
A(2, 1) = -24
A(2, 2) = -10
A(2, 3) = -57
A(3, 1) = 18
A(3, 2) = -11
A(3, 3) = 7

B(1) = 129
B(2) = -96
B(3) = 8.5
'==================

' set error handler
Call Call_ERSET(0, 0, 0)

' call IMSL routine
Call DLSARG(N, A(1, 1), LDA, B(1), IPATH, X(1))

' get any error codes
Error_code = Call_IERCD()
Error_type = Call_N1RTY(1)

' get solution
Solution(1) = X(1)
Solution(2) = X(2)
Solution(3) = X(3)

End Sub

Private Sub QUIT_BTN_Click()

End

End Sub

Private Sub SGEMV_BTN_Click()

Dim TRANS As String
Dim M As Long, N As Long
Dim SALPHA As Single, SBETA As Single
Dim SA(1 To 2, 1 To 2) As Single
Dim SX(1 To 2) As Single
Dim SY(1 To 2) As Single
Dim INCX As Long, INCY As Long
Dim LDA As Long
Dim Error_code As Long, Error_type As Long

ReDim Solution(2) As Single

TRANS = "N"

M = 2
N = 2
SALPHA = 3
SBETA = 1
SA(1, 1) = 1
SA(1, 2) = 2
SA(2, 1) = 3
SA(2, 2) = 4
SX(1) = 5
SX(2) = 6
SY(1) = 1
SY(2) = 2
INCX = 1
INCY = 1
LDA = 2

' turn off IMSL error printing and stopping
Call Call_ERSET(0, 0, 0)

' multiply the matrix and the vector with IMSL routine
Call SGEMV(TRANS, M, N, SALPHA, SA(1, 1), LDA, SX(1), INCX, SBETA, SY(1), INCY)

' get any IMSL Errors and severity
Error_code = Call_IERCD()
Error_type = Call_N1RTY(1)

' get solution
Solution(1) = SY(1)
Solution(2) = SY(2)

End Sub

Private Sub ZREAL_BTN_Click()

Dim ERRABS As Single, ERRREL As Single
Dim EPS As Single, ETA As Single
Dim NROOT As Long, ITMAX As Long
Dim Error_code As Long, Error_type As Long

' user input
'===========================
EPS = 0.00001
ERRABS = 0.00001
ERRREL = 0.00001
ETA = 0.01
ITMAX = 100
NROOT = 2

ReDim XGUESS(1 To NROOT) As Single
ReDim INFO(1 To NROOT) As Long
ReDim X(1 To NROOT) As Single
ReDim Solution(NROOT) As Single
ReDim Iterations(NROOT) As Single

XGUESS(1) = 4.6
XGUESS(2) = -193.3

' =========================

' turn off IMSL error printing and stopping
Call Call_ERSET(0, 0, 0)

' call IMSL routine
Call ZREAL(ERRABS, ERRREL, EPS, ETA, NROOT, ITMAX, XGUESS(), X(), INFO())

' get any IMSL Errors and severity
Error_code = Call_IERCD()
Error_type = Call_N1RTY(1)

' get solution and # iterations(N) to find the Nth zero
Solution(1) = X(1)
Solution(2) = X(2)
Iterations(1) = INFO(1)
Iterations(2) = INFO(2)

End Sub



Mike Linacre

  • Sr. Member
  • ****
  • Posts: 259
Re: How to create a wrapper DLL for IMSL functions
« Reply #1 on: October 20, 2007, 06:29:18 PM »
Thank you for your question,
but before we read through all that code, please tell us what the goal is:
Is it this?
You have a VB6 program from which you want to access a DLL written in Absoft Fortran which includes IMSL code (also in Absoft Fortran)
or what?
« Last Edit: October 20, 2007, 06:32:00 PM by Mike Linacre »

alanray

  • Guest
Re: How to create a wrapper DLL for IMSL functions
« Reply #2 on: October 23, 2007, 03:28:05 PM »
HI Mike
>>You have a VB6 program from which you want to access a DLL written in Absoft Fortran which includes IMSL code (also in Absoft >>Fortran)or what?

yes the MAIN reason I bought the Absoft package is because I have a VB6 program which needs various IMSL functions. Before I purchased the product I was assured that an DLL can be written in Absoft Fortran which would allow me to access the IMSL functions from VB6.

Since completing my purchase I find the reality is a bit different, as no example code seems to exist that actually demonstrates a DLL call to an IMSL function.

Mike Linacre

  • Sr. Member
  • ****
  • Posts: 259
Re: How to create a wrapper DLL for IMSL functions
« Reply #3 on: October 23, 2007, 06:41:09 PM »
Sounds like you have a four-stage problem:
1. Write a standard Absoft Fortran program that successfully accesses the IMSL functions.
2. Rewrite 1. so that the IMSL functions are accessed from a Fortran program via a Fortran DLL.
3. Write a VB6 program and a stub DLL in Absoft Fortran, and verify that they communicate correctly. The trickiest part is passing character variables between VB6 and Fortran. This is because of the VB6 indirect addressing mechanism. So be sure that the DLL interface includes all the variable types that you want to use.
4. Combine 2. and 3.

alanray

  • Guest
Re: How to create a wrapper DLL for IMSL functions
« Reply #4 on: October 24, 2007, 02:32:28 AM »
I have done item 1

I have extreme trouble with item 2 because of the need to pass an array structure between VB6 and Fortran.

That is why I have tried the approach instead of writing wrapper functions which my VB6 program can talk to.

Please look at my decelaration for dzreal

the problem I am having is with MYFCN, how do I declare it. Also I do not know if the array XGUESS and X are declared properly

stdcall   SUBROUTINE Call_DZREAL(MYFCN, ERRABS, ERRREL, EPS, ETA,NROOT, ITMAX, XGUESS, X, INFO)
      !   !DEC$ ATTRIBUTES DLLEXPORT :: Call_DZREAL
      !   !DEC$ ATTRIBUTES ALIAS:'Call_DZREAL' :: Call_DZREAL

      DOUBLE PRECISION,INTENT(IN) :: ERRABS
      DOUBLE PRECISION,INTENT(IN) :: ERRREL
      DOUBLE PRECISION,INTENT(IN) :: EPS
      DOUBLE PRECISION,INTENT(IN) :: ETA
      INTEGER,INTENT(IN) :: NROOT
      INTEGER,INTENT(IN) :: ITMAX
      DOUBLE PRECISION,INTENT(IN) :: XGUESS(NROOT)
      DOUBLE PRECISION,INTENT(OUT) :: X(NROOT)
      INTEGER,INTENT(IN) :: INFO(NROOT)

      CALL DZREAL (MYFCN, ERRABS, ERRREL, EPS, ETA, NROOT, ITMAX,XGUESS, X, INFO)

   END SUBROUTINE


alanray

  • Guest
Re: How to create a wrapper DLL for IMSL functions
« Reply #5 on: October 24, 2007, 02:33:58 AM »
In the code I have posted, most of my wrapper functions work, except for the ones that pass arrays such as ZREAL

Mike Linacre

  • Sr. Member
  • ****
  • Posts: 259
Re: How to create a wrapper DLL for IMSL functions
« Reply #6 on: October 24, 2007, 06:10:59 AM »
Yes, this is awkward. So we have to build up from simple situations ....
Can you pass a 2x2 integer array correctly? Put 1,2,3,4 in the cells and check that they are still 1,2,3,4 at the other end. Rows and columns and sequence often cause trouble. Adjust the array bounds so that VB6 and Absoft start arrays at the same lower limit (1 or 0).
Can you pass a double-precision (non-array) field correctly?
Then what happens when you try to pass a 2x2 double-precision array?

alanray

  • Guest
Re: How to create a wrapper DLL for IMSL functions
« Reply #7 on: October 24, 2007, 12:17:16 PM »
If for a moment we ignore IMSL I can certainly make a fortran DLL that interfaces with VB6.

I can pass integer, single precision and double precision arrays back and forth between VB6 and Fortran no problem.

But when IMSL gets in to the picture it gets very complicated.

Lets take an example .. the IMSL function NNLPF

CALL NNLPF (FCN,M,ME,IBTYPE,XLB,XUB,X)

XLB,XUB,X are all double precision arrays which in my case need to come from Visual Basic

FCN is to be declared as A User Supplied subroutine...

Internally NNLPF does CALL FCN(X,IACT,RESULT,IERR), so I have to tell  Fortran where is the Visual Basic function that needs to be executed.

OR

I need to supply a fortran function that can access array X.



Mike Linacre

  • Sr. Member
  • ****
  • Posts: 259
Re: How to create a wrapper DLL for IMSL functions
« Reply #8 on: October 24, 2007, 03:41:09 PM »
"I have to tell  Fortran where is the Visual Basic function that needs to be executed"

This is a challenge ... You need to obtain the address of a VB6 function. I've done this by writing dlls in VB6 and calling them from Fortran. So perhaps what you need is a Fortran mainline (including IMSL) which calls a VB6 dll that does whatever you need VB6 to do. But the only VB6  screen output that I've got to work properly from a VB6 dll is message boxes. The late-load technique (see another thread) gets around .obj and .lib problems when incorporating the VB6 .dll.

This suggests that you could shortcut the process by having VB6 write the arrays to disk and then shell (with wait) to an Absoft mainline which reads from disk and calls the IMSL routines, then writes its output to disk and terminates. The VB6 routine then continues by reading the IMSL output files from disk.

alanray

  • Guest
Re: How to create a wrapper DLL for IMSL functions
« Reply #9 on: October 24, 2007, 07:50:30 PM »
>>>
>>This suggests that you could shortcut the process by having VB6 write the arrays to disk and then shell (with >>wait) to an Absoft mainline which reads from disk and calls the IMSL routines, then writes its output to disk >>and terminates. The VB6 routine then continues by reading the IMSL output files from disk.

That is a most UNELEGANT solution...wow this is getting frustrating, I wonder if this is even possible.

ABSOFT sales told me it was possible ...all I want is a clean dll that reads my arrays, executes a function and give me an answer, not some kluge

Mike Linacre

  • Sr. Member
  • ****
  • Posts: 259
Re: How to create a wrapper DLL for IMSL functions
« Reply #10 on: October 25, 2007, 07:34:17 AM »
Sure, a shelled routine is inelegant. But it is robust, fast to produce, easy to debug and straight-forward to maintain. It's whether you want Tupperware or Waterford Crystal. ... That's the difference between "production programming" and "computer science". ... And the end-users can't tell the difference.

Absoft User Forum  |  Support  |  Windows  |  How to create a wrapper DLL for IMSL functions
 

gfxgfx
gfx gfx
Powered by MySQL Powered by PHP Valid XHTML 1.0! Valid CSS!