Vous êtes sur la page 1sur 4

18/6/2014 40562 - Defining a C function and calling it from the SAS System

http://support.sas.com/kb/40/562.html 1/4
Sample 40562: Defining a C function and calling it from the SAS System
Overview
This sample provides step-by-step instruction and guidance through the process of defining your own function in C, compiling your C code, and then calling your C function
from within a SAS DATA step. It is assumed that you are familiar with programming in C and compiling C source code.
The steps for defining a C function and calling it from SAS are as follows:
1. Define a function in C.
2. Compile the C source code into a shared library.
3. Perform a test call to the function from C.
4. Link SAS to the shared library with the PROTO procedure.
5. Define a SAS function with the FCMP procedure.
6. Store the SAS function as a compiled routine.
7. Call the function with DATA step.
Details
Step 1: Define a Function in C
The C function can be written in an editor of your choice, such as VI Editor or Microsoft Windows Notepad. This sample contains C source code for a function called
myfactorial that computes the factorial of an integer:
int myfactorial(int n){
int i;
int p;
for(p=1, i=2; i<=n; p=p*i, i++);
return p;
}
Note that you might need to modify your C source code based upon which compiler you use. The C program above is stored on the Downloads tab for this sample, and
the program is named myfactorial.c.
Step 2: Compile the C code
In order for SAS to be able to use a C program, the C source code must be compiled into a shared library. Note that shared libraries are platform specific. For instance, a
shared library that is compiled in an AIXoperating environment is not compatible with a Windows platform. You should consider each of the following factors when you
compile C source code:
Operating system (Examples: Windows, AIX, Solaris, and Linux)
CPU architecture (Examples: 32-bit and 64-bit)
Compiler (Examples: GCC and Microsoft Visual C++)
Operating system version (Examples: Windows versions are 7, Vista, and XP)
Compiler version (Examples: GCC versions are 4.5.1, 4.2.0, and 3.3.4)
These factors are especially important if your shared library is to be used on a machine other than the one on which it was compiled. Differences can result in an
incompatibility for the shared library.
There are several different C compilers. The configuration steps and command-line syntax that are required to compile your C source code is dependent upon which C
compiler you use. For example, you can use the following command-line syntax to compile the myfactorial.c program via the GCC 4.2.0 compiler on an AIX5.3 64-bit
platform:
gcc -maix64 -c -Wall -ansi -g -fPIC myfactorial.c
gcc -maix64 -shared -o myfactorial.so -fPIC myfactorial.o
The resulting myfactorial.so file is a shared library that can then be used by SAS.
As another example, you can use the following configuration steps to compile the myfactorial.c program via Microsoft Visual Studio 2010 in the Windows 7 operating
environment:
1. Create a new Visual C++ empty project.
2. Add myfactorial.c as a source file to the project.
3. Add myfactorial.def as a source file to the project, where myfactorial.def contains the following code:
LIBRARY "myfactorial"
EXPORTS
myfactorial @1
4. Edit the following project configuration properties in the Visual Studio 2010 Properties Pages window:
1. Select General in the navigation tree in the left pane of the Properties Pages window.
2. In the right pane, select Configuration Type, which displays a list. From that list, select Dynamic Library (.dll).
3. Click the Apply button. You must click Apply in order to edit the next properties.
4. In the left pane, select C/C++.
Providing software solutions since 1976
18/6/2014 40562 - Defining a C function and calling it from the SAS System
http://support.sas.com/kb/40/562.html 2/4
5. Under C/C++, select Code Generation.
6. In the right pane, select Runtime, which displays a list. From that list select Multi-Threaded (/MT).
7. In the left pane under C/C++, select Advanced.
8. In the right pane, select Calling Convention, which displays a list. From that list, select __stdcall (/Gz).
9. Click the OK button
5. Build the solution.
Notice the use of the definition file. As noted in the LINK statement section of the PROTO procedure documentation, many compilers do not export function names by
default. An external declaration of the function in the C source code using _declspec(dllexport) is one way to accomplish this, and a definition file is another way to
export the function names. The export program above is stored on the Downloads tab for this sample, and it is named myfactorial.def.
In addition to exporting function names, you might need to incorporate other modifications into your C source to account for features that vary according to the compiler
that you use. For example, some compilers perform name mangling of the functions during the source code compilation. For more specific details on the configuration
steps and syntax to use for your compiler, see the user manual for your compiler.
Step 3: Make a Test Call to the Function
This step is optional, but it is recommended. If you are not able to call your C function directly from C, outside of SAS, then there is a strong likelihood that a call to the
function from within SAS also will fail.
The following C test program calls the myfactorial function with an input argument of 6:
#include <stdio.h>
int main(int argc, char** argv) {
int n=6;
int out;
out=myfactorial(n);
printf("%d\n",out);
return (0);
}
This test program is stored on the Downloads tab for this sample, and it is named testmyfactorial.c. You can use the following command-line syntax to execute the
testmyfactorial.c test program to call the myfactorial function in the myfactorial.so shared library via the GCC 4.2.0 compiler on an AIX5.3 64-bit platform:
gcc -maix64 testmyfactorial.c myfactorial.so
./a.out
The output is 720.
Step 4: Link to the Library Using the PROTO Procedure
Use PROC PROTO to link SAS to the shared library that contains your C function. Sample 32080 provides greater detail for this step and the remaining steps, and the
PROTO procedure documentation also contains relevant information. To use a C function in SAS, the corresponding shared library needs to be linked via the LINK
statement. The following SAS code links SAS to the shared library and loads the function declarations to the Work.Proto_ds.Cfcns function package:
proc proto stdcall package=work.proto_ds.cfcns;
link 'c:\temp\myfactorial.dll';
int myfactorial(int n) ;
run;
This SAS code assumes that the myfactorial.dll shared library is stored in the C:\temp directory. The .dll extension in the filename indicates that the shared library was
compiled under Windows and that this code is being executed in a Windows environment. The STDCALL option in the PROC PROTO statement indicates that the
myfactorial.dll shared library was compiled on a Windows 32-bit platform using the __stdcall convention.
A successful execution of the SAS code above results in the following SAS log details:
NOTE: 'c:\temp\myfactorial.dll' loaded from specified path.
NOTE: Prototypes saved to WORK.PROTO_DS.CFCNS.
NOTE: PROCEDURE PROTO used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Step 5: Define a SAS Function Using the FCMP Procedure
A C function that is linked to SAS is only available to specific SAS procedures, such as the FCMP and COMPILE procedures. PROC FCMP is a Base SAS procedure,
and PROC COMPILE is a SAS Risk Dimensions procedure. This sample uses PROC FCMP, but the syntax for PROC COMPILE is similar.
When you use PROC FCMP, it is possible both to directly call a C function and to define a function that is available to the DATA step and many SAS procedures. The
following SAS code defines a SAS function called sas_myfactorial that contains a call to the myfactorial C function:
proc fcmp inlib=work.proto_ds outlib=work.fcmp_ds.sasfcns;
function sas_myfactorial(x);
return (myfactorial(x));
endsub;
quit;
This SAS code uses the INLIB= option to specify where the myfactorial C function information is stored, and it uses the OUTLIB= option to specify where to store the
SAS function sas_myfactorial that is defined. A successful execution of the SAS code above prints the following output to the SAS log:
NOTE: 'c:\temp\myfactorial.dll' loaded from specified path.
NOTE: Function sas_myfactorial saved to work.fcmp_ds.sasfcns.


18/6/2014 40562 - Defining a C function and calling it from the SAS System
http://support.sas.com/kb/40/562.html 3/4
NOTE: PROCEDURE FCMP used (Total process time):
real time 0.03 seconds
cpu time 0.01 seconds
Step 6: Store the Compiled SAS Routine
Use the SAS CMPLIB= system option to specify the storage locations for the C and FCMP functions:
options cmplib=(work.proto_ds work.fcmp_ds);
Execution of this SAS statement is necessary in order for your functions to be available to other SAS procedures and to the DATA step.
Step 7: Call the Function Using a DATA Step
It is now possible to call your function from the DATA step. From the DATA step, you need to call the FCMP function (sas_myfactorial in this sample) instead of the C
function. The DATA step recognizes that the sas_myfactorial function is available because it has been saved to a CMPLIB library. The SAS function sas_myfactorial,
in turn, calls the myfactorial C function, which was compiled in the myfactorial.dll shared library to which SAS was linked in the PROC PROTO step. In the following
SAS code, the argument 6 is passed to the function:
data _null_;
x=sas_myfactorial(6);
put x=;
run;
When the argument is passed to the myfactorial C function, the calculated result is returned to the SAS function sas_myfactorial, which is in turn passed back to the
DATA step. The flow of the full process is: DATA step FCMP PROTO C FCMP DATA step.
Upon successful execution of the SAS code above, the following note is printed to the SAS log:
NOTE: 'c:\temp\myfactorial.dll' loaded from specified path.
x=720
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds
The resulting value of 720 is consistent with the result that was produced from the C test program that is noted above in Step 3.
The SAS code from the four previous steps above is stored on the Downloads tab for this sample. That program is named myfactorial.sas.
Additional Documentation
SAS Institute Inc. 2009. SAS Sample 32080, "Using the PROTO procedure to call C functions from within a DATA step." Cary, NC: SAS Institute Inc. Available at
support.sas.com/kb/32/080.html.
SAS Institute Inc. 2007. SAS Sample 26151, "Create user-defined functions with PROC FCMP." Cary, NC: SAS Institute Inc. Available at
support.sas.com/kb/26/151.html.
SAS Institute Inc. 2007. "User-Written DATA Step Functions." SAS Global Forum 2007 Cary, NC: SAS Institute Inc. Available at
www2.sas.com/proceedings/forum2007/008-2007.pdf.
SAS Institute Inc. 2008. "CMPLIB= System Option" in SAS 9.2 Language Reference: Dictionary, Third Edition. Cary, NC: SAS Institute Inc. Available at
support.sas.com/documentation/cdl/en/lrdict/59540/HTML/default/base-sysop-cmplib.htm.
SAS Institute Inc. 2008. SAS Note 31738, "SAS crashes when running PROC PROTO." Cary, NC: SAS Institute Inc. Available at
support.sas.com/kb/31/738.html.
SAS Institute Inc. 2008. "The FCMP Procedure" in Base SAS 9.2 Procedures Guide. Cary, NC: SAS Institute Inc. Available at
support.sas.com/documentation/cdl/en/proc/59565/HTML/default/ a002890483.htm.
SAS Institute Inc. 2008. "The PROTO Procedure" in Base SAS 9.2 Procedures Guide. SAS Institute Inc. Cary: NC. Available at
support.sas.com/documentation/cdl/en/proc/59565/HTML/default/a002890473.htm.
These sample f iles and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of
merchantability and f itness f or a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable f or any damages whatsoever arising out of their use of this
material. In addition, SAS Institute will provide no support f or the materials contained herein.
These sample f iles and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of
merchantability and f itness f or a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable f or any damages whatsoever arising out of their use of this
material. In addition, SAS Institute will provide no support f or the materials contained herein.
The following files are referenced on the Details tab of this sample:
myfactorial.c
myfactorial.def
testmyfactorial.c

18/6/2014 40562 - Defining a C function and calling it from the SAS System
http://support.sas.com/kb/40/562.html 4/4
myfactorial.sas
This sample walks through the setup of defining a function in C code and then calling that C function from within a SAS program
Type: Sample
Topic: SAS Reference ==> Procedures ==> FCMP
SAS Reference ==> Functions ==> External Routines
SAS Reference ==> DATA Step
Third Party ==> Programming
Date Modified: 2010-09-09 14:07:44
Date Created: 2010-08-11 11:26:47
Operating System and Release Information
Product Family Product Host
Product Release SAS Release
Starting Ending Starting Ending
SAS System Base SAS Microsoft Windows for 64-Bit Itanium-based Systems 9.21 9.2 TS2M0
Microsoft Windows Server 2003 Datacenter 64-bit Edition 9.21 9.2 TS2M0
Microsoft Windows Server 2003 Enterprise 64-bit Edition 9.21 9.2 TS2M0
Microsoft Windows XP 64-bit Edition 9.21 9.2 TS2M0
Microsoft Windows for x64 9.21 9.2 TS2M0
Microsoft Windows Server 2003 Datacenter Edition 9.21 9.2 TS2M0
Microsoft Windows Server 2003 Enterprise Edition 9.21 9.2 TS2M0
Microsoft Windows Server 2003 Standard Edition 9.21 9.2 TS2M0
Microsoft Windows Server 2003 for x64 9.21 9.2 TS2M0
Microsoft Windows Server 2008 for x64 9.21 9.2 TS2M0
Microsoft Windows XP Professional 9.21 9.2 TS2M0
Windows Vista 9.21 9.2 TS2M0
Windows Vista for x64 9.21 9.2 TS2M0
64-bit Enabled AIX 9.21 9.2 TS2M0
64-bit Enabled HP-UX 9.21 9.2 TS2M0
64-bit Enabled Solaris 9.21 9.2 TS2M0
HP-UXIPF 9.21 9.2 TS2M0
Linux 9.21 9.2 TS2M0
Linux for x64 9.21 9.2 TS2M0
OpenVMS on HP Integrity 9.21 9.2 TS2M0
Solaris for x64 9.21 9.2 TS2M0
Contact Us | Sitemap | RSS Feeds | www.sas.com| Terms of Use & Legal Inf ormation | Privacy Statement
Copyright 2014 SAS Institute Inc. All Rights Reserved.

Vous aimerez peut-être aussi