From: Francogrex on 12 Dec 2009 09:44 Hi, This isn't an easy question, actually it's very tough and I expect only very experienced programmers to know the answer. I'm trying to use the modulen function to let sas connect and use a dll. My dll takes as an input a pointer and an integer and returns a pointer. Here is the code of the dll that I called sas.dll: #ifdef BUILD_DLL #define EXPORT __declspec(dllexport) #else #define EXPORT __declspec(dllimport) #endif #include <stdio.h> #include <stdlib.h> EXPORT double __stdcall *test (double *x, int n) { double *end=malloc((n+5)*sizeof(double)); int i; for (i=0; i<n;i++) { *end=x[i]*2; } return(end); } Now from SAS I use: filename sascbtbl catalog 'work.api.ZIAD'; data _null_; file sascbtbl; input; put _infile_; cards4; routine test minarg=2 maxarg=2 stackpop=called module=sas returns=long; arg 1 num input byaddr format=RB8. ; arg 2 num input byvalue format=PIB4. ; ;;;; run; data _null_; array vals(4) (12 2 13 4); rc= modulen ('*e', 'test',vals(1),1); put rc=; testme=peek(rc,8); put testme=; run; This works well. Giving: rc=72351536 and testme=24 But I am just giving one values as an argument to the sas.dll. What I want is to directly pass the WHOLE array arr as an argument (pointer) and then use something like rc= modulen ('*e', 'test', {WRONG SYNTAX ALL ARRAY vals}, 4); ret1=peek(rc,8) ; ret2=peek(rc+8,8); etc.. to read the returned result. Any ideas how?
From: Barry Schwarz on 12 Dec 2009 11:45 On Sat, 12 Dec 2009 06:44:07 -0800 (PST), Francogrex <franco(a)grex.org> wrote: >Hi, This isn't an easy question, actually it's very tough and I expect >only very experienced programmers to know the answer. I'm trying to >use the modulen function to let sas connect and use a dll. My dll >takes as an input a pointer and an integer and returns a pointer. Here >is the code of the dll that I called sas.dll: >#ifdef BUILD_DLL >#define EXPORT __declspec(dllexport) >#else >#define EXPORT __declspec(dllimport) >#endif >#include <stdio.h> >#include <stdlib.h> >EXPORT double __stdcall *test (double *x, int n) >{ > double *end=malloc((n+5)*sizeof(double)); You allocate an array of n+5 doubles. > int i; > for (i=0; i<n;i++) > { > *end=x[i]*2; You repeatedly store different values in the first element of that array. Obviously, only the last value stored survives in the element. The remaining n+4 elements have indeterminate values. Did you intend instead end[i] = x[i] * 2; This will populate the first n elements of the array. The last 5 will still be indeterminate. > } > return(end); >} > >Now from SAS I use: > >filename sascbtbl catalog 'work.api.ZIAD'; >data _null_; > file sascbtbl; > input; > put _infile_; > cards4; > routine test > minarg=2 > maxarg=2 > stackpop=called > module=sas > returns=long; > >arg 1 num input byaddr format=RB8. ; >arg 2 num input byvalue format=PIB4. ; >;;;; >run; >data _null_; > array vals(4) (12 2 13 4); > rc= modulen ('*e', 'test',vals(1),1); > put rc=; > testme=peek(rc,8); > put testme=; >run; > >This works well. Giving: rc=72351536 and testme=24 > >But I am just giving one values as an argument to the sas.dll. What I >want is to directly pass the WHOLE array arr as an argument (pointer) >and then use something like > >rc= modulen ('*e', 'test', {WRONG SYNTAX ALL ARRAY vals}, 4); >ret1=peek(rc,8) ; >ret2=peek(rc+8,8); >etc.. >to read the returned result. Any ideas how? -- Remove del for email
From: Francogrex on 12 Dec 2009 16:17 On Dec 12, 5:45 pm, Barry Schwarz <schwa...(a)dqel.com> wrote: > You allocate an array of n+5 doubles. > > > int i; > > for (i=0; i<n;i++) > > { > > *end=x[i]*2; > > You repeatedly store different values in the first element of that > array. Obviously, only the last value stored survives in the element. > The remaining n+4 elements have indeterminate values. > > Did you intend instead > end[i] = x[i] * 2; > This will populate the first n elements of the array. The last 5 will > still be indeterminate. > Oops yes it was a typing error while I was typing it here in the newsgroup; that line above should read: *(end+i)=x[i]*2; Of course since it is correct in the original C file that compiled to the sas.dll my stated problem before still remains. Any suggestions?
From: Savian on 12 Dec 2009 17:17 On Dec 12, 7:44 am, Francogrex <fra...(a)grex.org> wrote: > Hi, This isn't an easy question, actually it's very tough and I expect > only very experienced programmers to know the answer. I'm trying to > use the modulen function to let sas connect and use a dll. My dll > takes as an input a pointer and an integer and returns a pointer. Here > is the code of the dll that I called sas.dll: > #ifdef BUILD_DLL > #define EXPORT __declspec(dllexport) > #else > #define EXPORT __declspec(dllimport) > #endif > #include <stdio.h> > #include <stdlib.h> > EXPORT double __stdcall *test (double *x, int n) > { > double *end=malloc((n+5)*sizeof(double)); > int i; > for (i=0; i<n;i++) > { > *end=x[i]*2; > } > return(end); > > } > > Now from SAS I use: > > filename sascbtbl catalog 'work.api.ZIAD'; > data _null_; > file sascbtbl; > input; > put _infile_; > cards4; > routine test > minarg=2 > maxarg=2 > stackpop=called > module=sas > returns=long; > > arg 1 num input byaddr format=RB8. ; > arg 2 num input byvalue format=PIB4. ; > ;;;; > run; > data _null_; > array vals(4) (12 2 13 4); > rc= modulen ('*e', 'test',vals(1),1); > put rc=; > testme=peek(rc,8); > put testme=; > run; > > This works well. Giving: rc=72351536 and testme=24 > > But I am just giving one values as an argument to the sas.dll. What I > want is to directly pass the WHOLE array arr as an argument (pointer) > and then use something like > > rc= modulen ('*e', 'test', {WRONG SYNTAX ALL ARRAY vals}, 4); > ret1=peek(rc,8) ; > ret2=peek(rc+8,8); > etc.. > to read the returned result. Any ideas how? I cannot answer your direct question since I have never used modulen but let me ask a few questions that might lead to alternatives (assuming others cannot give a direct response). 1. What O/S are you running on? 2. Can you skip a datastep and use an X command instead? 3. Do you have a data volume problem? If I need processing external to SAS (which I do on every single project), I tend to code it up and read in the SAS datasets, process, then put it back into SAS format. This does not work with large volume but it is an idea. That way, I control all aspects of the interface. Alan http://www.savian.net
From: Francogrex on 12 Dec 2009 17:29 On Dec 12, 11:17 pm, Savian <savian....(a)gmail.com> wrote: > I cannot answer your direct question since I have never used modulen > but let me ask a few questions that might lead to alternatives > (assuming others cannot give a direct response). > > 1. What O/S are you running on? > 2. Can you skip a datastep and use an X command instead? > 3. Do you have a data volume problem? > > If I need processing external to SAS (which I do on every single > project), I tend to code it up and read in the SAS datasets, process, > then put it back into SAS format. This does not work with large volume > but it is an idea. That way, I control all aspects of the interface. I use winXP. I know how to pipe commands to a cmd, write to external temp files that other programs can use and spit back their outputs into sas, but that's not what I want, sorry. I really need to pass an array as an argument to a dll and get back an array of values in return. I know how to get an array of values in return (see below), what is still missing is passing the array to the dll as one argument. This works because arguments are not pointers sas.c file: EXPORT double __stdcall *test (double x, double y,int n) { double *end=malloc((n+5)*sizeof(double)); int i; for (i=0; i<n; i++) { *(end+i)=(x+y)*i; } return(end); } filename sascbtbl catalog 'work.api.myfile'; data _null_; file sascbtbl; input; put _infile_; cards4; routine test minarg=3 maxarg=3 stackpop=called module=sas returns=long; arg 1 num input byvalue format=RB8. ; arg 2 num input byvalue format=RB8. ; arg 3 num input byvalue format=PIB4. ; ;;;; run; data _null_; rc = modulen ('*e', 'test', 7.3, 4.6, 15); do i=0 to 14*8 by 8; testme=peek(rc+i,8); put testme=; end; run;
|
Next
|
Last
Pages: 1 2 3 4 Prev: Programmer Productivity using EE, Next: need help with the GLIMMIX for Goodness-of -fit |