C
C#•3mo ago
Demonik

Crossplatform VarArg PInvoke

What's the current correct way to declare PInvoke C library function with vararg parameters that works on at least Mac, Windows, Android and Linux? I know the actual maximum number of parameters so I don't care if I have to write multiple functions, what I'm interested in is if it will work correctly on all platforms.
9 Replies
Demonik
Demonik•3mo ago
(function is opus_encoder_ctl from libopus) my idea is to declare 2 functions for different parameter lists and wrappers around them but I'm not sure if that'll correctly follow calling conventions on all platforms looking through information on the interet I found __arglist keyword but I'm finding very conflicting information on if it's ok to use and if it works on other platforms and defining multiple functions also can't find any information on if it will work on all target platforms
jcotton42
jcotton42•3mo ago
@Demonik I would ask this in #allow-unsafe-blocks
Demonik
Demonik•3mo ago
ty, I'll ask there
cap5lut
cap5lut•3mo ago
variadic arguments r afaik not possible at ABI level, but that was regarding c++. in #allow-unsafe-blocks this question (again for c++) comes up quite often and the recommended way was always to write a thin wrapper c library that does the varargs stuff for u. oh sorry, just looked at the timestamps and noticed im late to the party 😒
Demonik
Demonik•3mo ago
I just added 1 and 2 arg variants to libopus and rebuilt it I'll just have to do it for all platforms the library itself is pure C the worst part is there doesn't seem to be any reason why it's exposed like that in public api, all it is is a function that receives request id and 1 or 2 arguments based on request, so it could've been just a bunch of 1 / 2 argment functions, yes it would've increased amount of functions exposed because there are like 7 of these _ctl functions and a lot of them share same requests, but still is shitty api design
cap5lut
cap5lut•3mo ago
i dunno much about C, i would guess maybe they couldnt come up with good names for the different functions, but looking at C function names generally ... u know xD
Demonik
Demonik•3mo ago
I mean if you look at docs they literally have names for the functions as #defines which are passed to the vararg as 2nd argument
cap5lut
cap5lut•3mo ago
arent those macros?
Demonik
Demonik•3mo ago
yes but they were used as constants example of a function OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); this is example of defines
#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
you're supposed to call it like opus_encoder_ctl(encoder, OPUS_SET_VBR_CONSTRAINT(arg)) and it wlll call it like opus_encoder_ctl(encoder, 4020, arg) there is no reason I see why it couldn't have been opus_encoder_set_vbr_constraint(encoder, arg) it's a shitty api design that clearly ignores that languages other than C exist this is just one function that does a lot of things depending on 2nd argument this doesn't really translate to any language other than C and only works in C because of typechecking hacks used in macros