0

I am developping a C++/CLI library and I have the following class:

public ref class AbstractClassA abstract{
  protected:
    // signature can be changed by me (method will be overriden in C#)
    virtual void write(String ^ str, String ^ format, ...array<Object^> ^args) = 0; 
  internal:
    // signature cannot be changed by me
    void internWrite(const char *str, const char *format, va_list args){
      write(gcnew String(str), gcnew String(format), ???)}
};

The method 'internWrite' must call the method 'methodA' but I am not able to find how to convert the 'va_list' parameter to a managed array. I found some interesting posts [1], [2] but the mentionned solutions require to have the 'va_list' lenght. I do not have these information and I cannot change the signature of 'internWrite'.

I can change the signature of 'write'.

How can I convert va_list to a managed variable args array ?

[EDIT] The comments of the method 'internWrite' mention:

-format + args: formated print, same syntax as printf function

Maybe I need use the parameter 'format' to get the length of the va_list (as mentionned on length of va_list when using variable list arguments?). But how can I do that? How the printf command does that ?

[EDIT] Making the hypothesis that format+args have the same syntax as printf, I create a method to get the lenght of agrs (by countinh the '%'). Here is my code at this moment:

void write(char *format, va_list args){
    String^ mgFormat = gcnew String(format);
    int nbArgs = sizeOfArgs(format);
    array<Object^>^ mgArgs = gcnew array<Object^>(nbArgs);

    va_start(args, format);
    for (int _i = 0; _i < nbArgs; ++_i){
        mgArgs[_i] = va_arg(args, int); // not sure the type is int ... how to know ?
    }
    va_end(args);
    internWrite(mgFormat, mgArgs);
    }

But now I am stucked about adding each arg object to the array because the macro 'va_arg' requires the type of the current argument. I do not have this information. How to iterate va_list and fill my managed array?

[1] How do I pass variable arguments from managed to unmanaged with a C++/CLI Wrapper?
[2] Calling a .NET function with variable number of parameters from unmanaged code

Community
  • 1
  • 1
ltu
  • 169
  • 3
  • 16
  • For managed C++/# you have to use `params` keyword: `func( params object[] arg );`. – i486 Dec 19 '14 at 13:49
  • 1
    If you have no way to get the length of the va_list, it sounds pretty hopeless. – Medinoc Dec 19 '14 at 13:52
  • As i see, you have a format string, which perfectly specifies the number of arguments expected once it is parsed. For a printf-like format string, you could count those '%' characters in the format string which are not preceded or succeeded immediately by another '%' char. – Géza Török Dec 19 '14 at 13:57
  • Géza Törötk: thank you. Since it is mentionned that it uses the printf syntax, I will count % as you proposed. i486: yes I will use this signature in my C# code Medinoc: hope I will find a solution ... – ltu Dec 19 '14 at 14:12
  • 1
    Unless you know the format string is constrained to 32-bit types, you can't assume each argument is in fact an `int` or at least the same size. You will have to not only count the `%` characters, but also look at the format character following it and adjust the size of each `va_arg` accordingly. But I don't understand the code example. You show both `write` calling `internWrite` and `internWrite` calling `write`, which is an infinite loop! You should make a code example that shows clearly the exact relationship between caller and callee, including code that uses this class. – Peter Duniho Dec 19 '14 at 16:48

1 Answers1

0

It seems like you need to parse the format argument, in order to determine both the number of arguments and the type of the arguments. The va_list doesn't contain the type information, it seems like.

A suggestion, if you really want to go down that road, is to read the vsnprintf documentation, but it seems like some work lies ahead of you!

Even

holroy
  • 3,047
  • 25
  • 41