(Declares) any workaround for calling variadic function in 64-bit?

I understand from the User Guide and this thread that Xojo does not support variadic functions under 64-bit (actually, it’s only by luck that they can be used in 32-bit).

As “luck” would have it, I am using a variadic function from a library. It’s worked fine under 32-bit for years, but now as I try to make the transition to 64-bit (Mac OS, for now), I’m running into this blocker. There is a “VA” version of the method, which does the same thing, but accepts a va_list instead of a variable number of args. Is it maybe possible to use that as a workaround?

Original function signature is:

foo* Func(const char *arg0, ...)

And the “VA” version is:

foo* Func_VA(const char *arg0, va_list ap)

I’m not sure how to go about creating a va_list in Xojo, though. I have found some documentation on the va_list structure, but it is not clear to me how I’d construct that in Xojo.

Any ideas or other suggestions for working around the variadic function issue in 64-bit?

if va_list is a structure, most of the times you can create such struct in Xojo and pass it to a declare.
Some structures are not easily replicable in Xojo, in that case you can recurse to a memoryBlock and fill it. After all a structure is block of memory…

Right…that is what I thought, too. But I can’t seem to figure out what the structure actually is. There is a snippet on this post in StackOverflow showing it:

// Figure 3.34 typedef struct { unsigned int gp_offset; unsigned int fp_offset; void *overflow_arg_area; void *reg_save_area; } va_list[1];

But the link in that same post that claims to go to the detailed documentation is broken. I have no idea what the items in the structure are supposed to be/how I’d arrange things on the Xojo side (there is a description in the SO post but I don’t understand it).

Hi Joshua - This link works (Internet Archive to the rescue)

https://web.archive.org/web/20160801075139/http://www.x86-64.org/documentation/abi.pdf

@Anthony Dellos Indeed that link functions, thanks :slight_smile: There is even a little algorithm there that explains the process in some detail (pg 53-54). Unfortunately, that explanation is a bit beyond my understanding as far as trying to make something in Xojo that would work. And actually I’m kind of skeptical it would work anyway.

I’m thinking what I might end up doing is write an intermediary library with non-variadic functions that Xojo can pass things to. The intermediary library would then hand off to the variadic function(s) in the main library I’m trying to work with.

Best approach. Make a plugin for this or a library to declare into that removes handing va_list in Xojo.

If you still want to follow this approach:
You can either use a memory block or a structure for this function. The structure would be

gp_offset As UInt32 fp_offset As UInt32 overflow_arg_area As Ptr reg_save_area As Ptr
or the Memoryblock would have to be 22 Bytes (64 Bit) or 16 Bytes long (32 Bit), containing the values in the order as above.

So your declared function would take a Cstring and either a Ptr or the structure as input parameters.

I hope you meant 32 or 16.

No, I should have meant
24 (2 Ptrs 8 Byte = 16 + 2 UInt32 4 Byte = 8)
or
16 (2 Ptrs 4 Byte = 8 + 2 UInt32 4 Byte = 8) :smiley:

Maybe :slight_smile:

  1. The va_list is actually a one-element array. This fact seemed to be an issue for one of the folks answering in the Stack Overflow link that I posted earlier:
  1. Ignoring the details of the structure itself: that is not really what I have difficulty understanding. It’s the content. What goes into gp_offset, fp_offset, overflow_arg_area, reg_save_area? How are my input args to be arranged? For example, from the description:

Not sure how I would determine what “the place where the next available general purpose argument register is saved”…? Who or what sets this? Everything that I can find for creating a va_list (in C/C++) refers to the va_start, va_arg, and va_end macros…which can’t be used by Xojo. I tried digging around to try to figure out what those macros are under the hood, but I got pretty lost in stdarg.h…

At any rate: I guess if someone wanted to experiment with an actual function that uses a va_list rather than my hypothetical: try writing a Declare that works for Mac x86_64 for one of the v*printf functions (vprintf, vfprintf, etc.), all of which take a va_list and which should be available in libc. If someone can do (or has already done?) that, I’d love to see the Xojo code…