Marshal va_list in C# delegate

后端 未结 4 578
孤城傲影
孤城傲影 2021-01-13 08:04

I\'m trying to make this work from c#:

C header:

typedef void (LogFunc) (const char *format, va_list args);
         


        
4条回答
  •  渐次进展
    2021-01-13 08:44

    Just in case it helps someone, here's a solution for marshaling the arguments. The delegate is declared as:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl, SetLastError = true)] // Cdecl is a must
    internal delegate void LogFunc(string format, IntPtr argsAddress);
    

    The argsAddress is the unmanaged memory address where the array starts (I think). The format gives the size of the array. Knowing this I can create the managed array and fill it. Pseuso-code:

    size <- get size from format
    if size = 0 then return
    
    array <- new IntPtr[size]
    Marshal.Copy(argsAddress, array, 0, size);
    args <- new string[size]
    
    for i = 0 to size-1 do
       placeholder <- get the i-th placeholder from format // e.g. "%s"
       switch (placeholder)
           case "%s": args[i] <- Marshal.PtrToStringAnsi(array[i])
           case "%d": args[i] <- array[i].ToString() // i can't explain why the array contains the value, but it does
           default: throw exception("todo: handle {placeholder}")
    

    To tell the truth, I'm not sure how this works. It just seems to get the right data. I'm not claiming it is correct though.

提交回复
热议问题