Science makes it known,
Engineering makes it work,
Art makes it beautiful.
|
|
Using a simple D program to call Pascal .dll - Pascal files
The Pascal backend of
D Programming Language, Free Pascal, and Financial Functions. It was written using the Free Pascal IDE 2.6.4 on an
AMD Athlon II running WinXP Pro SP3.
Free Pascal
is a 32, 64, and 16 bit Object Pascal compiler for multiple
hardware platforms
(Intel x86, AMD64/x86-64, PowerPC, PowerPC64, SPARC) and operating
systems (DOS, Win32, Win64, Linux, FreeBSD, Mac OS X/iOS/Darwin, OS/2).
The 32 bit version is used for compatibility with D2 32-bit and
SilverFrost Fortran compilers.
finance.pas1
- Pascal source file of financial functions; compiles into dynamic link
Library (or .dll), not Unit. Compiled with the
Free Pascal dialect switch turned on.
Contains D callable2
FUNCTIONs VIF (...) (Value Interest Factor),
CMPT_PV (...) (compute Present Value),
CMPT_FV (...) (compute Future Value), and
NPVPROJCT (...) (Project Net Present Value);
all return a Single ( ≡ D's float type);
other functions/procedures may be added in the future.
|
|
Avoid using Pascal Integer and Real types in Librarys,
especially in the passed parameter list
- instead use
Smallint, Longint, Single, or
Double. This is for compatibility with D and FORTRAN data
types. See
Variable Storage Compatibility and Equivalency
for additional information.
Note the number of float array elements difference of dfinc.d's
extern (Pascal)
{
float CMPT_PV (ref short, ref short, ref float, ref float);
float CMPT_FV (ref short, ref short, ref float, ref float);
float NPVPROJCT (ref short, ref short, ref float[200], ref float[200], ref float, ref float);
}
.
float[200] ft, pt;
.
.
NPV = NPVPROJCT (iErr, n, pt, ft, k, a0);
and finance.pas'
TenYearsPrjData = ARRAY[1..120] of single;
.
.
.
// Project Net Present Value
// A0 : initial cash investment (passed as negative, outflow)
// k : required rate of return
// F : F(i) net cash flow period i
// P : P(i) predicted rate of inflation period i
// n : number of months (periods)
FUNCTION NPVPROJCT (VAR A0, k : single;
VAR F, P : TenYearsPrjData;
VAR n, iErr : smallint) : single; stdcall;
While not efficient, it is not a problem (done intentionally to demonstrate
concept). As a rule, the calling program array s/b as large as or larger then
the array in the called program. Usually when passing an array, the calling
program passes the
start address of the array. It is also a good idea to pass the
number of array elements actually used,
and do some rudimentary error checking on that number.
(Reminder - when using extern (Pascal) in D program to call
FORTRAN/Pascal subprograms, D passes the arguments in reverse
order)
Compiling and Linking
See screenshot lower right. Since finance.dll is being called by a D
main program, this is a two step process - compile and link into a
.dll using fpcdll (download and description below), then
build .lib import library using implib (download and
description below). Open a D2 32-bit Command Prompt, then type in:
fpcdll finance
to build finance.dll from finance.pas. D linking requires import libraries;
Digital Mars supplies an utility with their D compiler to build import libraries
from dynamic link libraries.
To build the import library, type in:
implib finance.lib finance.dll
fpcdll.bat
- batch file
to compile Pascal source file into .dll file using
-WR
switch (generate a relocatable library; can be moved to another memory
location if the desired ImageBase address is already in use); see
Free Pascal Programmer’s Guide, type fpc -h in a Command
Prompt for more information.
implib -
DMD utility used to create an Intel 32 bit OMF import library file format
finance.lib from finance.dll.
*.lib files are required for dmd D compiler to reference
functions/procedures in
*.dll files during D main program compiling/linking, as can be
seen in dmd compile/link command to the right.
|
|
To execute dfinc.exe, in a MS-DOS command prompt simply type dfinc
as shown above.
1. Screen shots taken during initial prototyping, finance.pas
has since been enhanced, including making fPOW (...) public
(externally callable) and calculate negative powers as 1 / r**abs(p).
Download and examine revised source code. Current version of dfinc.d
calls and outputs results of Present Value and Future Value (not shown in
screenshot).
2. Only those procedures with all upper case names are D callable. This
is a side effect of using
extern (Pascal) {...}.
Can also be called by procedures written in other languages, including
Pascal.
|