C#从CPP调用参数数目未知的CPP函数
我在CPP中有一个具有以下原型的函数:C#从CPP调用参数数目未知的CPP函数,c#,c++,interop,pinvoke,variadic-functions,C#,C++,Interop,Pinvoke,Variadic Functions,我在CPP中有一个具有以下原型的函数: char* complexFunction(char* arg1, ...); 我使用DLLImport属性从C#导入它。 问题是: 如何在C#(DLLImport属性下)中定义原型? 如何将参数传递到此函数? 谢谢这就是所谓的可变函数。关于P/Invoke对它们的支持的信息非常少,下面是我发现的 我找不到直接DllImport一个参数数量可变的函数的方法。我必须DllImport将参数的所有变体作为不同的重载 让我们举个例子。它在winuser.h中具
char* complexFunction(char* arg1, ...);
我使用DLLImport属性从C#导入它。
问题是:
如何在C#(DLLImport属性下)中定义原型?
如何将参数传递到此函数?
谢谢这就是所谓的可变函数。关于P/Invoke对它们的支持的信息非常少,下面是我发现的 我找不到直接
DllImport
一个参数数量可变的函数的方法。我必须DllImport
将参数的所有变体作为不同的重载
让我们举个例子。它在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);
}
}
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);
}
}
现在来解决您的complexFunction
char* complexFunction(char* arg1, ...);
它的varargs列表应该以相同的方式处理:通过提供所有有用的重载。但还有另一个复杂因素——返回类型。我假设complexFunction
分配并返回char
的数组。在这种情况下,调用方很可能负责数组的释放。为了实现这一点,您还应该导入释放例程,我们将其称为voidfree(void*)
假设所有这些都是假设的,使用complexFunction
的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);
}
}
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);
}
}