- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm the original poster of the question.
I added the suggested !DEC$ line and it worked fine.
Thanks Steve,
Ron
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page