Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

unable to convert argument ... #34

Closed
daurnimator opened this issue Jun 1, 2012 · 8 comments
Closed

unable to convert argument ... #34

daurnimator opened this issue Jun 1, 2012 · 8 comments

Comments

@daurnimator
Copy link

I'm having trouble reducing to a small test case, but things work fine under luajit.

When running the code:

local mask = ffi.new ( "sigset_t[1]" )
ffi.C.sigemptyset ( mask )

I get the error: unable to convert argument 1 from cdata<struct 61[1]> to cdata<struct 26*>

sigemptyset is declared via:

typedef struct
  {
    unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))];
  } __sigset_t;
extern int sigemptyset (sigset_t *__set) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));

though the trailing attributes don't seem to matter

@jmckaskill
Copy link
Owner

 sigset_t != __sigset_t

@daurnimator
Copy link
Author

Except when it is :p
Sorry, I missed typedef __sigset_t sigset_t; in the paste before.
And the code still has the same error if I change my ffi.new invocation to use __sigset_t

@jmckaskill
Copy link
Owner

OK so the following works for me with lua 5.2 on OSX.

typedef struct
  {
    unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))];
  } __sigset_t;
typedef __sigset_t sigset_t;
extern int sigemptyset (sigset_t *__set) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));

So the question is why does it not work for you...
Can you copy the output of:

require 'pretty' -- this is just a table pretty printer I included in the src
print(table.show(ffi.debug()))  -- This dumps the symbol, type table, etc.

After the cdef call.

@daurnimator
Copy link
Author

Okay....
Btw, I warned you I was having trouble cutting the test case down :P

(damn, github cut off the file..... can I email it to you? what addr?)

@jmckaskill
Copy link
Owner

in ffi.debug().functions

      ["sigemptyset"] = "ctype<int (*)(struct 24*)> 0x2266128" {
         ["env"] = {}; -- __unnamed__["functions"]["sigpending"]["env"] (self reference)
         ["mt"] = {}; -- __unnamed__["functions"]["rewind"]["env"][1]["env"][1]["mt"] (self reference)
      };

      ["sigpending"] = "ctype<int (*)(struct 24*)> 0x2268ad8" {
         ["env"] = {
            [1] = "ctype<struct 24*> 0x2265f18" {
               ["env"] = {}; -- __unnamed__["functions"]["__sigdelset"]["env"][1]["env"] (self reference)
               ["mt"] = {}; -- __unnamed__["functions"]["rewind"]["env"][1]["env"][1]["mt"] (self reference)
            };
            [0] = "ctype<int> 0x2265f98" {
               ["env"] = {}; -- __unnamed__["functions"]["rewind"]["env"][1]["env"][1]["env"] (self reference)
               ["mt"] = {}; -- __unnamed__["functions"]["rewind"]["env"][1]["env"][1]["mt"] (self reference)
            };
            ["userdata: 0x7f08f4e13c6c"] = "int (*";
            ["userdata: 0x7f08f4e13c70"] = ")(struct 24*)";
            ["userdata: 0x7f08f4e13c68"] = "int (*)(struct 24*)";
         };
         ["mt"] = {}; -- __unnamed__["functions"]["rewind"]["env"][1]["env"][1]["mt"] (self reference)
      };

in ffi.debug().types

      ["__sigset_t"] = "ctype<struct 59> 0x222ad58" {
         ["env"] = {}; -- __unnamed__["functions"]["epoll_pwait"]["env"][5]["env"] (self reference)
         ["mt"] = {}; -- __unnamed__["functions"]["rewind"]["env"][1]["env"][1]["mt"] (self reference)
      };

So it is indeed getting confused. I wonder if its getting confused with the first reference being circular.
Can you perchance email me the full ffi.cdef content and/or include it here?

@jmckaskill
Copy link
Owner

OK so first off there is two typedef struct {...} __sigset_t (line 99 and 1109), which is illegal C. The parser should be erroring on that.

Otherwise this is a case of types (including function types) created between the first and second __sigset_t typedef use the first definition, but later types and your use of ffi.new use the second definition.

For now get rid of the double definitions. The bug in luaffi is to then error on the second definition.

@daurnimator
Copy link
Author

Ah okay; I hadn't noticed I had duplicate declarations.

somehow luajit didn't seem to choke: maybe because they were identical declarations?
Are you able to copy that behaviour?

Thanks :)

@jmckaskill
Copy link
Owner

I'm very loathe to allowing duplicate definitions. Strictly speaking duplicates aren't allowed by the FFI API, it's just luajit has a implementation detail at the moment where it doesn't error, but that doesn't preclude it from erring in the future. From the FFI semantics page:

Also, this is not a validating C parser. It expects and accepts correctly formed C declarations, but it may choose to ignore bad declarations or show rather generic error messages. If in doubt, please check the input against your favorite C compiler.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants