BookmarkSubscribeRSS Feed
vioravis
Calcite | Level 5

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;

7 REPLIES 7
FriedEgg
SAS Employee

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...

vioravis
Calcite | Level 5

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.

vioravis
Calcite | Level 5

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;

FriedEgg
SAS Employee

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.

chrwag
Calcite | Level 5

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.

FriedEgg
SAS Employee

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.

chrwag
Calcite | Level 5

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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 2381 views
  • 0 likes
  • 3 in conversation