Это называется вариадной функцией. Информация о поддержке P / Invoke для них довольно скудна, вот что я узнал.
Я не смог найти способ напрямую DllImport
функции с переменным числом аргументов. Мне пришлось DllImport
все варианты аргументов как различные перегрузки.
Давайте возьмем для примера wsprintf . Имеет следующий прототип в winuser.h
:
int WINAPIV wsprintf(
LPTSTR lpOut,
LPCTSTR lpFmt,
...);
Может использоваться из C # следующим образом:
using System;
using System.Text;
using System.Runtime.InteropServices;
class C {
// first overload - varargs list is single int
[DllImport("user32.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int wsprintf(
[Out] StringBuilder buffer,
string format,
int arg);
// second overload - varargs list is (int, string)
[DllImport("user32.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int wsprintf(
[Out] StringBuilder buffer,
string format,
int arg1,
string arg2);
public static void Main() {
StringBuilder buffer = new StringBuilder();
int result = wsprintf(buffer, "%d + %s", 42, "eggs!");
Console.WriteLine("result: {0}\n{1}", result, buffer);
}
}
Теперь обращайтесь к вашему complexFunction
.
char* complexFunction(char* arg1, ...);
Его список varargs должен обрабатываться таким же образом: путем предоставления всех полезных перегрузок. Но есть и другое осложнение - тип возврата. Я предполагаю, что complexFunction
выделяет и возвращает массив char
. В этом случае наиболее вероятно, что вызывающая сторона ответственна за освобождение массива. Для этого вам также следует импортировать подпрограмму освобождения, назовем ее void free(void*)
.
Предполагая, что все, что предполагалось, код C # с использованием complexFunction
будет выглядеть так:
using System;
using System.Text;
using System.Runtime.InteropServices;
class C {
[DllImport("your.dll",
CallingConvention=CallingConvention.Cdecl,
CharSet=CharSet.Ansi)]
static extern IntPtr complexFunction(
string format,
int arg1, int arg2);
[DllImport("your.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void free(IntPtr p);
public static void Main() {
IntPtr pResult = complexFunction("%d > %s", 2, 1);
string sResult = Marshal.PtrToStringAnsi(pResult);
free(pResult);
Console.WriteLine("result: {0}", sResult);
}
}