- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to call C++ DLL from SAS and am trying to recreate the example given in the following paper:
http://www.members.cox.net/mhiemstra/C_With_SAS.pdf
I am using Visual C++ Express 2008 (Windows 64 Bit Machine) to build the DLL and I did not get any errors. I place the foolib DLL in system32 folder and tried running the following SAS code. However, I ended up getting an error that Module foolib could not be loaded. Can someone please let me know what is causing this error?? Thank you.
76 DATA _NULL_;
77 InNum = 2;
78 OutNum = MODULEN('*E', 'square', InNum);
79 PUT "******************************";
80 PUT " The input is: " InNum;
81 Put "The square of the input is: " OutNum;
82 PUT "******************************";
83 RUN;
ERROR: Module foolib could not be loaded.
NOTE: Invalid argument to function MODULEN at line 78 column 10.
******************************
The input is: 2
The square of the input is: .
******************************
InNum=2 OutNum=. _ERROR_=1 _N_=1
NOTE: Mathematical operations could not be performed at the following places. The results of the
operations have been set to missing values.
Each place is given by: (Number of times) at (Line):(Column).
1 at 78:10
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
84 QUIT;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Did you build the attribute table in SAS for the function so that it knows how to work with the C routine?
In the document you linked see step 1...
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
FriedEgg,
Both the attribute table definition and the C function have been taken out of the same paper. They are in pages 4 and 6 respectively. Could you please elaborate on your statement?? Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I have posted the C function defined below and the corresponding SAS code. Thank you.
/* foolib.c */
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved ) { return TRUE; }
double __stdcall square(double d) { return d*d; }
*****************************************************************************************;
/* foolib.def */
LIBRARY FooLib
DESCRIPTION 'Sample Library Function'
EXETYPE WINDOWS
EXPORTS
square
FILENAME SASCBTBL "work.temp.attrfile.source"; /* PC */
/* FILENAME SASCBTBL "sascbtbl.dat"; */ /* Unix */
DATA _NULL_;
FILE SASCBTBL;
INPUT;
PUT _INFILE_;
CARDS4;
ROUTINE square
MINARG = 1
MAXARG = 1
STACKPOP = CALLED
MODULE = foolib
RETURNS = DOUBLE;
ARG 1 NUM BYVALUE FORMAT=RB8.;
;;;;
RUN;
DATA _NULL_;
InNum = 2;
OutNum = MODULEN('*E', 'square', InNum);
PUT "******************************";
PUT " The input is: " InNum;
Put "The square of the input is: " OutNum;
PUT "******************************";
RUN;
QUIT;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Did you check that the function is working properly itself?
C:\WINDOWS\System32\rundll32.exe <dllname>,<entrypoint> <optional arguments>
Also, try replacing '*E' with '*I' for possibly better debug information.
You may also need to register the dll. See the regsvr32 command in windows command prompt.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I am stuck at the same problem at the moment.
It works fine with the first example on this page (http://www.devenezia.com/downloads/sas/sascbtbl/). Works without registering the dll.
If I try it the same way with my dll (coying it in system32 folder) I receive the error "Module AD_Wagen could not be loaded.".
I uploaded the c file for example.The dll shoud only return the value 1909 to keep it simple.
In SAS I tried this:
filename SASCBTBL catalog 'WORK.WINAPI.WINAPI.SOURCE';
data _null_;
file SASCBTBL;
input ;
put _infile_;
cards4;
routine AD_Wagen
module = AD_Wagen
minarg = 0
maxarg = 0
CALLSEQ=BYVALUE
STACKORDER=R2L
STACKPOP=CALLER
returns = short;
ARG 1 output num format=ib4.;
;;;;
data _null_;
rc = modulen ('*i','AD_Wagen');
run;
My Log shows:
NOTE: Module AD_Wagen could not be loaded.
NOTE: Invalid argument to function MODULE at line 522 column 8.
_ERROR_=1 _N_=1
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
I hope someone could help me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Have you verified that the dll file is working properly iteself, using for instance rundll32 as I suggested earlier?
You define min and maxarg=0 yet you define arg 1, output here does not have any relevance to the value the dll returns. Output is a argument that is not converted, but is updated with an outgoing value from the DLL routine.
You define module=AD_Wagen, make sure the dll file you placed in you system32 folder is called AD_Wagen.dll or you should change this value.
I also beleive you want stackpop=called instead of caller, but I am not quite sure about this.
It also does look like the function AD_Wagen you are wanting to call has several arguments it is expecting yet as I mention earlier you are defining none.
Best of luck, sorry I cannot provide much help in this area.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I found a solution and it works now.
Testing the dll by calling rundll32 showed that cc3250mt.dll was not found. This dll belongs to the Borland C++ compiler. So I had to install the compiler. I also had to copy the borland dll to my system32 folder.