这与从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代码。有什么建议让它发挥作用吗?
答案 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全球论坛。)