Author Topic: Parameter passing to dll - difference VAC / GCC - varargs  (Read 4534 times)

Andi B.

  • Hero Member
  • *****
  • Posts: 873
  • Karma: +14/-2
    • View Profile
Parameter passing to dll - difference VAC / GCC - varargs
« on: January 20, 2024, 01:50:50 pm »
I've a dll which exports functions which I wanna call from VAC, GCC (and Watcom) compiled programs.

Problem is gcc seems to pass varargs different than VAC.
I've a function in the dll something like
Code: [Select]
ULONG         _System   xPmPrintf(char *Format, ...);which works when called by programs compiled with VAC3.65 but produces garbage when called by a gcc test program (except the first arg).

I found here http://trac.netlabs.org/odin32/ticket/19 that Dmitriy noted about a problem with gcc and varargs but can't find a solution.

Any hints?

Digi

  • Jr. Member
  • **
  • Posts: 69
  • Karma: +4/-1
  • http://os2.snc.ru/
    • View Profile
    • OS/2 ports and applications
Re: Parameter passing to dll - difference VAC / GCC - varargs
« Reply #1 on: January 21, 2024, 10:30:22 pm »
In my opinion, it is a very bad idea to use varargs in exported functions.

It might be useful for you to see how a similar task is solved in libxml2:

File xmlwriter.c
/*
 * The following VA_COPY was coded following an example in
 * the Samba project.  It may not be sufficient for some
 * esoteric implementations of va_list but (hopefully) will
 * be sufficient for libxml2.
 */
#ifndef VA_COPY
  #ifdef HAVE_VA_COPY
    #define VA_COPY(dest, src) va_copy(dest, src)
  #else
    #ifdef HAVE___VA_COPY
      #define VA_COPY(dest,src) __va_copy(dest, src)
    #else
      #ifndef VA_LIST_IS_ARRAY
        #define VA_COPY(dest,src) (dest) = (src)
      #else
        #include <string.h>
        #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
      #endif
    #endif
  #endif
#endif


And SDL2. File SDL_vacopy.h
/* Do our best to make sure va_copy is working */
#if defined(__NGAGE__)
#undef va_copy
#define va_copy(dst, src) dst = src

#elif defined(_MSC_VER) && _MSC_VER <= 1800
/* Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment */
#undef va_copy
#define va_copy(dst, src) dst = src

#elif defined(__GNUC__) && (__GNUC__ < 3)
#define va_copy(dst, src) __va_copy(dst, src)
#endif


And use in your xPmPrintf something like that:
va_copy(local_va_list, given_va_list);
vsnprintf(..., ..., fmt, local_va_list);
va_end(local_va_list);


Andi B.

  • Hero Member
  • *****
  • Posts: 873
  • Karma: +14/-2
    • View Profile
Re: Parameter passing to dll - difference VAC / GCC - varargs
« Reply #2 on: January 23, 2024, 07:10:20 pm »
Thanks.

In the meantime I found out that my problem is NOT an incompatibility between GCC/VAC as I thought before.

I fear va_copy is not supported by any IBM compiler. At least I didn't find anything in ibmcpp3xx and ibmcpp4. Is this a gcc only thing?

Dave Yeo

  • Hero Member
  • *****
  • Posts: 5098
  • Karma: +117/-1
    • View Profile
Re: Parameter passing to dll - difference VAC / GCC - varargs
« Reply #3 on: January 23, 2024, 07:40:30 pm »
Looks like it is a C99 thing, so the IBM compilers are too old.
https://en.cppreference.com/w/c/variadic/va_copy