Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

pass string to call_external

frink
2013-04-19
2013-08-04
  • frink
    frink
    2013-04-19

    Hey,
    i have troubles passing a string to call_external by reference. 

    This Code is working with the /ALL_VALUE keyword:

    #include <stdio.h>
    char* input(int argc, char* argv[]){
      char* a= argv[0];
      return a;
    }
    

    The GDL-session:

    GDL> print,call_external('./libexample.so','input',"test",/S_VALUE,/ALL_VALUE)
    test
    

    …is working fine.

    But, as the documentation says: "The default is to pass all parameters by reference."

    So, i try this code:

    #include <stdio.h>
    char* input(int argc, char** argv[]){
      char* a= *argv[0];
      return a;
    }
    

    In gdl:

    print,call_external('./libexample.so','input',"test",/S_VALUE)
    

    Gives a memory-error.

    What is wrong here?

    Thanks!

     
  • Alain C.
    Alain C.
    2013-04-22

    I tested using: gcc -shared -lm test1.c -o libexample1.so
    and received same "results" than you in GDL and also in IDL … Second code is wrong, isn't it ?

    Alain

     
  • giloo
    giloo
    2013-04-22

    call_external(library, x) passes the *address* of x instead of x. the (argc,argv)  mechanism retrieves whatever value was passed, but goes no further. It is up to the called library to know what kind of object was passed and point to it through its passed address. 
    I suggest to take examples from the source of a C library made to be also called from CALL_EXTERNAL like OptimPack (google for it, OptimPack libraries can be called from gdl without problems (op_test.pro works) ).  The functions called are defined like, e.g.,  'extern const char* myfunc(int argc, void *argv); arguments are retrieved inside myfunc as, eg., get_integer(argv) and get_integer has to be written (see code).
    HTH
    PS Optimpack is GPL'd….

     
  • Marc Schellens
    Marc Schellens
    2013-04-22

    I read Gilles reply too late, now I send this nevertheless as I already wrote it :-)

    In case of 'reference' and a GDL_STRING passed,  a new (malloc) EXTERN_STRING* is passed.
    typedef struct {
        int   slen;
        short stype;
        char  *s;
      } EXTERN_STRING;
    (in basic_pro_jmp.hpp)

    so you need something like:
    #include <stdio.h>
    char* input(int argc, char* argv)
    {
    EXTERN_STRING* a=(EXTERN_STRING*) argv;
    return a.s;
    }
    (untested )
    HTH

     
  • frink
    frink
    2013-04-22

    Thank you, for your replies.
    I now found the[ original documentation [/url of the command.
    And the Code

    ](https://sourceforge.net/tracker/index.php?func=detail&aid=3096214&group_id=97659&atid=618685)

    #include <stdio.h>
    typedef struct {
      int slen;
      short stype;
      char *s;    
    } EXTERN_STRING;
    char* input(int argc, void* argv[]){
      EXTERN_STRING* a=(EXTERN_STRING*) argv[0]; 
      printf("%s\n",(*a).s);
      return (*a).s; 
    }
    

    [Seems to be okay, in the sense, that C gets the string correctly (printf), but the returned string is empty in gdl:

    ](https://sourceforge.net/tracker/index.php?func=detail&aid=3096214&group_id=97659&atid=618685)

    GDL> print,call_external('./libexample.so','input',"test",/s_value)
    test
    

    [This is strange, as

    ](https://sourceforge.net/tracker/index.php?func=detail&aid=3096214&group_id=97659&atid=618685)

    char *hello(){
      return "Hello, world!";
    }
    

    [is working correctly:

    ](https://sourceforge.net/tracker/index.php?func=detail&aid=3096214&group_id=97659&atid=618685)

    GDL> help,call_external('./libexample.so','hello',/s_value)
    <Expression>    STRING    = 'Hello, world!'
    

    [ Futher curios: If i call the command with "/unload", GDL crashes:

    ](https://sourceforge.net/tracker/index.php?func=detail&aid=3096214&group_id=97659&atid=618685)

    GDL> help,call_external('./libexample.so','hello',/s_value,/unload)
    

    Does anybody know, what's the problem with this example?

     
  • frink
    frink
    2013-04-22

    Incorrect link command in my last post:
    Thank you, for your replies.
    I now found the original documentation of the command.
    And the Code

    #include <stdio.h>
    typedef struct {
      int slen;
      short stype;
      char *s;    
    } EXTERN_STRING;
    char* input(int argc, void* argv[]){
      EXTERN_STRING* a=(EXTERN_STRING*) argv[0]; 
      printf("%s\n",(*a).s);
      return (*a).s; 
    }
    

    Seems to be okay, in the sense, that C gets the string correctly (printf), but the returned string is empty in gdl:

    GDL> print,call_external('./libexample.so','input',"test",/s_value)
    test
    

    This is strange, as

    char *hello(){
      return "Hello, world!";
    }
    

    is working correctly:

    GDL> help,call_external('./libexample.so','hello',/s_value)
    <Expression>    STRING    = 'Hello, world!'
    

    Futher curios: If i call the command with "/unload", GDL crashes:

    GDL> help,call_external('./libexample.so','hello',/s_value,/unload)
    

    Does anybody know, what's the problem with this example?

     
  • giloo
    giloo
    2013-08-01

    Hi,
    I've checked. This is a bug i can reproduce.
    GDL's CALL_EXTERNAL seem not to work with strings.
    We'll have to investigate.
    thanks

     
  • giloo
    giloo
    2013-08-01

    Hi,
    It works now.

     
  • Alain C.
    Alain C.
    2013-08-04

    Gilles or Frink,

    could you prepare/consider to add the pertinent example(s) in the test suite ?
    (It might help in the future for any regression; I also
    make changes in the call_external() code but too lazy to
    try to find what to do with the codes here, sorry)

    Thanks

    Alain