将SAS连接到C库

时间:2010-09-16 13:26:59

标签: c sas

这与从SAS调用C函数(制作动态库)有关。有4个文件。前2个(1个c文件和1个sas文件)是使用双精度的阳性对照。其余文件存在问题。

C-FILE-1

#ifdef BUILD_DLL  
#define EXPORT __declspec(dllexport)  
#else  
#define EXPORT __declspec(dllimport)  
#endif  
#include "stdio.h"  
#include "stdlib.h"  
#include "string.h"  

EXPORT void test (double *inarray, double *outarray, int n)  
{    
int i;   
 for (i=0; i<n;i++)  
   {  
     outarray[i]= inarray[i]*2;  
   }  
 return;  
}  

// gcc -c -DBUILD_DLL pointersVoid.c
// gcc -shared -o pointersVoid.dll pointersVoid.o

SAS-FILE-1

filename sascbtbl catalog 'work.api.MYFILE';  
data _null_;  
    file sascbtbl;  
    input;  
    put _infile_;  
    cards4;  
    routine test  
    module=pointersVoid    
    minarg=3  
    maxarg=3;  
arg 1 input num byvalue format=IB4.;  
arg 2 input num byvalue format=IB4.;  
arg 3 input num byvalue format=PIB4.;  
;;;;  
run;  
data test;  
  array arr(5)  _temporary_  (7.56 2.356 63.54 5.14 8.2);  
  array ret(5);  
    rc=modulen ("*e","test",addr(arr(1)), addr(ret(1)), 5);  
run;  

这很好用,ret数组现在包含原始值的* 2。 但是当我们使用字符串时,我们会收到错误:

C-FILE-2

#include "stdio.h"  
#include "stdlib.h"  
#include "string.h"  

char *strtrim_right(char *p)  
{  
    char *end;  
    int len;  
    len = strlen(p);  
    while (*p && len)  
    {  
        end = p + len-1;  
        if(isalpha(*end))  
            *end = 0;  
        else  
            break;  
        len = strlen(p);  
    }  
    return(p);  
}  

EXPORT char **test (char **x, char **y, int n)  
{  
    int i;  
    for (i = 0; i < n; i++)  
    {  
        y[i] = strtrim_right(x[i]);
    }
}

/*
gcc -c -DBUILD_DLL pointers-array-string-void.c  
gcc -shared -o pointers-array-string-void.dll pointers-array-string-void.o   
*/

SAS-FILE-2

filename sascbtbl catalog 'work.api.MYFILE';  
data _null_;  
    file sascbtbl;  
    input;  
    put _infile_;  
    cards4;  
    routine test  
    module=pointers-array-string-void  
    minarg=3  
    maxarg=3;  
arg 1 input char byvalue format=$CSTR200. ;  
arg 2 input char byvalue format=$CSTR200. ;  
arg 3 input num byvalue format=PIB4. ;  
;;;;  
run;  
data test;  
    array arr(5) $ _temporary_ ('PM23RO' '85AB12RE' 'RE147AMF' 'TAGH14MMF' 'LCA2Q');  
    array ret(5) $;  
    call module ("*e","test",addr(arr(1)), addr(ret(1)), 5);  
run;  

这不起作用并给出错误:

Unrecognized option - in ROUTINE statement
NOTE: Invalid argument to function MODULE
ret1=  ret2=  ret3=  ret4=  ret5=  rc=. _ERROR_=1 _N_=1

我知道C-FILE-2运行良好,因为dll已经从另一个应用程序进行了测试,因此很可能是SAS-FILE-2中的SAS代码。有什么建议让它发挥作用吗?

1 个答案:

答案 0 :(得分:0)

在64位SAS中,您将要使用addrlong并将模块参数声明更新为format=$ptr. datalen=8

如果您的.dll是32位,您仍然应该可以通过添加routine声明选项dlltype=32来调用其例程。 ("When I'm 64-bit: How to Still Use 32-bit DLLs in Microsoft Windows" Rick Langston,2015 SAS全球论坛。)