Calling a C function with a varargs argument dynamically

前端 未结 10 1426
太阳男子
太阳男子 2020-12-05 11:45

I am programming in C against a third party library (in HP/Mercury Loadrunner) that allows a varargs-style variable size argument list for one of it\'s functions. I want to

10条回答
  •  感动是毒
    2020-12-05 11:54

    Since it's generally not a problem to pass more arguments to a function taking variable arguments than the function expects (see footnote #1), you can do something like the following:

    // you didn't give a clear specification of what you want/need, so this 
    // example may not be quite what you want as I've had to guess at
    // some of the specifications. Hopefully the comments will make clear
    // what I may have assumed.
    //
    // NOTE:  while I have compiled this example, I have not tested it,
    //        so there is a distinct possiblity of bugs (particularly
    //        off-by-one errors). Check me on this stuff, please.
    
    // I made these up so I could compile the example
    #define ITEMDATA ((char const*) NULL)
    #define ENDITEM  ((char const*) 0xffffffff)
    
    void web_submit_data_wrapper( const char*bufferName, 
                                  const char* bufferValue, 
                                  size_t headerCount,       // number of header pointers to pass (8 in your example)
                                  size_t itemStartIndex,    // index where items start in the buffers (11 in your example)
                                  size_t itemCount,         // number of items to pass (unspecified in your example)
                                  size_t dataSize )         // size of each header or item (129 in your example)
    {
        // kMaxVarArgs would be 3000 or a gazillion in your case
    
        // size_t const kMaxVarArgs = 20;  // I'd prefer to use this in C++
        #define kMaxVarArgs (20)
    
        typedef char const* char_ptr_t;
        typedef char_ptr_t char_ptr_array_t[kMaxVarArgs];
    
        char_ptr_array_t varargs = {0};
    
        size_t idx = 0;
    
        // build up the array of pararmeters we'll pass to the variable arg list
    
        // first the headers
        while (headerCount--) {
            varargs[idx++] = &bufferName[idx * dataSize];
        }
    
        // mark the end of the header data
        varargs[idx++] = ITEMDATA;
    
        // now the "items"
        while (itemCount--) {
            varargs[idx++] = &bufferName[itemStartIndex * dataSize];
            varargs[idx++] = &bufferValue[itemStartIndex * dataSize];
            varargs[idx++] = ENDITEM;
    
            ++itemStartIndex;
        }
    
        // the thing after the last item 
        // (I'm not sure what this is from your example)
        varargs[idx] = &bufferName[itemStartIndex * dataSize];
    
        // now call the target function - the fact that we're passing more arguments
        //  than necessary should not matter due to the way VA_ARGS are handled 
        //  but see the Footnote in the SO answer for a disclaimer
    
        web_submit_data( 
            varargs[0],
            varargs[1],
            varargs[2],
    
            //... ad nasuem until
    
            varargs[kMaxVarArgs-1]
            );
    
    }
    

    Footnote #1: If you think about how the macros in stdargs.h act this becomes clear. However, I do not claim that this technique would be standards compliant. In fact, in recent history the stackoverflow answers I've posted where I;ve made this disclaimer have in fact been found to be non-standards compliant (usually by the ever vigilant litb). So use this technique at your own risk, and verify, verify, verify).

提交回复
热议问题