Вот способ справиться с этим. Это может или не может быть применимо к вашему случаю, в зависимости от того, предназначены ли ваши аргументы обратного вызова для использования с printf
семейством функций.
Сначала импортируйте vsprintf
и _vscprintf
из msvcrt
:
[DllImport("msvcrt.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int vsprintf(
StringBuilder buffer,
string format,
IntPtr args);
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int _vscprintf(
string format,
IntPtr ptr);
Далее объявите свой делегат с указателем IntPtr
args:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public unsafe delegate void LogCallback(
void* arg1,
int level,
[In][MarshalAs(UnmanagedType.LPStr)] string fmt,
IntPtr args);
Теперь, когда ваш делегат вызывается через собственный код, просто используйте vsprintf
, чтобы правильно отформатировать сообщение:
private void LogCallback(void* data, int level, string fmt, IntPtr args)
{
var sb = new StringBuilder(_vscprintf(fmt, args) + 1);
vsprintf(sb, fmt, args);
//here formattedMessage has the value your are looking for
var formattedMessage = sb.ToString();
...
}