Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Calling a Fortran routine from SAS

postaquestion
Novice
975 Views

I want to call a fortran routine from SAS.

SAS has extensive interface commands that allow specification of the .dll name, call-by-value vs call-by-reference, number and type of arguments, etc. To check that I was doing things correctly in SAS, I was able to successfully call a system .dll (KERNEL32.dll, routine Beep) and it worked correctly.

Unfortunately, I wasn't able to get SAS to use a .dll routine using the Intel Fortran compiler (version 7.1, command line). I get an address error. Here's an example fortran program:

Subroutine ABC(X1)
!DEC$ ATTRIBUTES DLLEXPORT :: ABC
Implicit Double Precision (A-H,O-Z)
X1 = X1 + 5.0
Return
End

Here's the compile statement (command line):

ifl /LD abc.for
(I then move abc.dll to a directory included in the PATH)

Here's the SAS routine definition file:

routine ABC
minarg=1 maxarg=1
stackpop=called
callseq=byaddr
module=abc;
arg 1 num update format=RB8.;

And the SAS code:

filename sascbtbl "c:sassascbtbla.dat";
data _null_;
x1 = 5;
call module ('*IT','ABC',x1);
put x1;
run;


And the SAS results:
ATTR: modname=ABC arglen=8 argndec=0 argiou=UPDATE argreqd=1 argtype=1 argfdst=0
infmtname/fmtname=RB
---PARM LIST FOR MODULE ROUTINE---
CHR PARM 1 09845393 2A4954 (*IT)
CHR PARM 2 09845390 414243 (ABC)
NUM PARM 3 098452E8 0000000000001440
---ROUTINE ABC LOADED AT ADDRESS 09881000 (PARMLIST AT 0294FC0C)---
PARM 1 0984A008 0000000000001440
ERROR: Read Access Violation In Task [ DATASTEP )
Exception occurred at (0983FEB0)
Task Traceback
Address Frame (DBGHELP API Version 4.0 rev 5)


I've also tried changing to call-by-value and eliminating the passed parameters with no success.

I would greatly appreciate any help you could provide.

0 Kudos
2 Replies
Steven_L_Intel1
Employee
975 Views
7.1??? Aren't you a bit behind the times?

Anyway, most every language I've seen that does calls to DLLs requires that the called routine use the STDCALL calling mechanism. Try changing the directive to:

!DEC$ ATTRIBUTES DLLEXPORT,STDCALL,REFERENCE,ALIAS:"_ABC" :: ABC
0 Kudos
fortranuser
Beginner
975 Views

I'm the original poster of the question.

I added the suggested !DEC$ line and it worked fine.

Thanks Steve,

Ron

0 Kudos
Reply