Hi, I'm quite new to Nim, although I've been following the language for awhile 
now. This is probably a simple misunderstanding of the FFI on my part, but I 
was wondering if anyone could advise on why I'm getting the errors I am. I'm 
trying to wrap the [C client](https://github.com/cleishm/libneo4j-client) to 
the [Neo4j graph database](https://neo4j.com/). Consider this subset of the 
header file:
    
    
    // neo4j-client.h
    
    union _neo4j_value_data
    {
        uint64_t _int;
        uintptr_t _ptr;
        double _dbl;
    };
    
    struct neo4j_value
    {
        uint8_t _vt_off;
        uint8_t _type; /*TODO: combine with _vt_off? (both always have same 
value)*/
        uint16_t _pad1;
        uint32_t _pad2;
        union _neo4j_value_data _vdata;
    };
    
    typedef struct neo4j_value neo4j_value_t;
    
    __neo4j_pure
    neo4j_value_t neo4j_int(long long value);
    
    ssize_t neo4j_fprint(neo4j_value_t value, FILE *stream);
    
    

I wrote a small test program in C to check that I understand the interface. I 
simply create a variable `v` which stores a value that can be used with the 
database client and then print it. 
    
    
    #include <neo4j-client.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      neo4j_value_t v = neo4j_int(10);
      printf("%s\n", "Printing with neo4j-client function:");
      neo4j_fprint(v, stdout);
      printf("\n%s\n", "Was anything printed?");
      /* Output:
         
         Printing with neo4j-client function:
         10
         Was anything printed?
       */
      return EXIT_SUCCESS;
    }
    
    

I then wrote a wrapper and a small test as follows:
    
    
    import posix
    
    const
      libneo4j* = "libneo4j-client.so"
    
    type
      value_data* {.union, final, pure.} = object
        `int`*: uint64
        `ptr`*: cuint #uintptr_t
        `dbl`*: cdouble
      
      value_t* {.final, pure.} = object
        vt_off*: uint8
        `type`*: uint8
        pad1*: uint16
        pad2*: uint32
        vdata*: value_data
    
    proc newInt*(value: clonglong): value_t {.cdecl, importc: "neo4j_int", 
dynlib: libneo4j.}
    
    proc fprint*(value: value_t; stream: File): clonglong {.cdecl,
        importc: "neo4j_fprint", dynlib: libneo4j.}
    
    var v = newInt(10)
    echo repr v
    echo "Printing with neo4j-client function:"
    discard fprint(v, stdout)
    echo "\nWas anything printed?"
    #[ Output:
       
       [vt_off = 2,
       type = 2,
       pad1 = 0,
       pad2 = 0,
       vdata = [int = 10,
       ptr = 10,
       dbl = 9.881312916824931e-324]]
       
       Printing with neo4j-client function:
       
       Was anything printed?
    ]#
    

As you can see, although a `value_t` object seems to have been returned with 
the correct integer encoded, it isn't being printed properly. In fact, I find 
that none of the library functions which I try to wrap work properly with 
object arguments. Is there something obvious I'm missing here? Thanks in 
advance for any help.

Reply via email to