Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#从CPP调用参数数目未知的CPP函数_C#_C++_Interop_Pinvoke_Variadic Functions - Fatal编程技术网

C#从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中具

我在CPP中有一个具有以下原型的函数:

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);
  }
}