tags:

views:

61

answers:

0

This is related to calling C functions (made into dynamic libraries) from SAS. There are 4 files. the first 2 (1 c-file and 1 sas-file) are a positive control using doubles. The remaining files are the problematic.

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;  

This works fine and ret array now contains the *2 of the original values. But when we use strings we get errors:

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;  

This doesn't work and gives errors: Unrecognized option - in ROUTINE statement NOTE: Invalid argument to function MODULE ret1= ret2= ret3= ret4= ret5= rc=. ERROR=1 N=1

I know the C-FILE-2 works well because it's been tested (the dll) from another aplication, so ther error source is very likely the sas code in SAS-FILE-2 Any suggestions to make it work?