• Hi,
    Is there a limit to the number of arguments that can be passed to an inlined C function?
    I get a message

    Uncaught Error: Error Parsing signature at argument number 6

    when attempting to set up an inline C function with 6 arguments. Everything appears fine up to 4 arguments.
    Thanks,
    Marko

  • Yes - it's due to the way functions are stored in Espruino. If you're running low, best bet is to put all your arguments into a Uint32Array and then pass a pointer to that.

  • Hi Gordon, I just came accross this question here and I've the same problem as user113695. I followed your advice, but I just get "garbage" data delivered in my C-function.
    I'm not the C guy, so I definitly doing something wrong here
    C-Function:

    // int find_sequence(int, int, int, int)
        int find_sequence(unsigned char* buffer, unsigned char* sequence, unsigned int sequence_length, unsigned int* params) {... return params[0]; }
    

    And in the code I'm calling it with

    const result = findNative.find_sequence(
                E.getAddressOf(this.buffer, true),
                E.getAddressOf(sequence, true),
                sequence.length,
                E.getAddressOf(new Uint32Array([
                    this.idx,
                    this.next,
                    offset,
                    stepping
                ]), true)
    );
    

    The first three parameters are working beautifully. No matter if I'm accessing params[0], params[1], params[2] or params[3], they all seem to have random values stored within.

    Could you help out Gordon?
    Thank you very much in advance.

  • I also tried to change my C-function signature to

    int find_sequence(unsigned char* buffer, unsigned char* sequence, int sequence_length, int* params) {}
    

    And pass in an Int32Array. This does not work either. What I noticed is, that whenever I'm returning any of the values from params, I get a static value, which stays the same - so something more like a fixed memory address. But I read that accessing a value by ptr[X] automatically dereferences it and lets me access the value as *(ptr + 0) would do.

  • I think I had a similar problem back then. I believe that E.getAddressOf will only return the address to a flat memory area if the Array is above a certain size. Try padding your Uint32Array with a few 0s at the end.

  • Thank you for your reply. Your advice at least solves part of the problem. Now the first variable in the array params[0] is the expected value. But unfortunately not the others (params[1..n]).
    I tried padding the Uint32Array to 32bytes and 64bytes without any further luck. Do you have any other Idea? Does it have something to do with signed or unsigned bytes?

  • If I'm not passing the array as a flat data area in the ram, the source code says, that I'm getting an array of JSVar pointers instead. So would it be correct to have an **int params parameter then, since it's actually an array of pointers. How do I retrieve the value of this variable then? Is there some param[0]->get_value()? I did not find anything in the source code.
    But I actually would prefer the flat array option, since this makes working with the values far easier. As said in a comment above: I'm really not that into C at all. I'm just tinkering around with it. Thanks for any of your help.

  • Now it gets really strange: This works, but why?

    E.getAddressOf(new Int32Array([
                    begin, 0, 0, 0, 0, 0, 0, 0,
                    end, 0, 0, 0,
                    offset,
                    stepping
    ]), true)
    

    Accessing data at index 0, 8, 12 and 13. Any other "configuration" using different 0-spacings does not work. I'm completly lost.

  • the

    E.getAddressOf(new Uint32Array([
                    this.idx,
                    this.next,
                    offset,
                    stepping
                ]),
    

    will not last long, the array is not referenced anywhere so will be freed soon, assign it to some variable. The E.getAddressOf just gives memory address, it does not care about allocation.

  • Fanoush probably has a point here, regarding the temporary array getting cleaned up in garbage collection.
    Instead I have used a global auxiliary Uint32Array large enough to be in a flat memory area for passing in additional parameters. Not very elegant but works...

  • Take a look at the source for the View STL app (Bangle 1 only atm) - I use this technique quite a bit in it.

  • ... will not last long

    That'll be it. As soon as the address it retrieved the data is freed and then it gets overwritten by the next allocated variable!

    I'd also add a check to make sure that E.getAddressOf is returning as nonzero value. If for some reason the array isn't allocated in one chunk then getAddressOf won't return a pointer to it, and you don't want to be trying to dereference a null pointer in C.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Limit to number of arguments to inline C function

Posted by Avatar for user113695 @user113695

Actions