You cannot have varargs functions in a shared library.
Well, yes, but you can provide an .fd file which will for all practical means works like a varargig function (is this a proper word?)
As Thomas already said (the other Thomas, not me), you write a function which accepts as last argument a tag list. Then, for the library, you create an ".fd" file which describes all your call-ins (LVOs, to be precise). The particular function name should have a "TagList" as last part of the function, e.g.
myFuncTagList(args,tags)(a0,a1)
Then, to create prototypes and pragmas for your compiler, get "FD2Pragma" from aminet. This is a tiny code generator which creates both prototypes and pragmas for a given fd file (see the guide for how to run it).
In particular, for calls like the above, it will create *two* pragmas and *two* prototypes: One for a function taking a pointer to a tag list as second argument, and another vararg function which takes a list of tags as last arguments.
For the SAS/C, this is even more convenient as the compiler takes care of converting the argument list to a pointer during the function call, so the overhead is minimal (or even zero, depending on your point of view).
Essentially, SAS/C knows two types of library function calls:
#pragma libcall
which is the classical "put arguments in registers then call the library" and
#pragma tagcall
which is a "put all initial arguments in registers, but put all last arguments on the stack and then call the function with the argument of the list on the stack".
The nice part is that it does not take any sort of "stub" function, i.e. there is no need to write a function like the one Thomas suggested because, essentially, the compiler does it for you, and even inlines it. (With a grain of salt).
I do not know how other compilers handle this, though, and whether they offer a similar mechanism.