如何调用/调用“__arglist"功能? [英] How to P/Invoke "__arglist" function?
问题描述
背景:
我用 C++ 编写了以下函数:
Background:
I have written the following function in C++:
extern "C" __declspec(dllexport) int test(const char*, ...);
我使用 P/Invoke 从 C# 调用它:
And I am using P/Invoke to call it from C#:
[DllImport("foo/bar.dll", EntryPoint = "test")]
public static unsafe extern int __unmanaged__test(byte* buffer, __arglist);
<小时>问题:
我需要动态初始化 __arglist
,这意味着我有一个 Array
,我必须在调用之前将其转换为 __arglist
C++-函数.
Problem:
I need to initialize the
__arglist
dynamically, meaning that I have an Array<object>
, which I have to convert into the __arglist
before calling the C++-function.
我尝试了以下方法,但它返回一个编译器错误:
I have tried the following, but it returns an compiler error:
unsafe {
byte[] buffer = ....
object[] args = ....
// ....
fixed (byte* ptr = buffer)
return __unmanaged__test(ptr, __arglist(args)); // <--ERROR
}
有人知道解决这个问题的方法吗?
Does anyone know a way to solve this problem?
<小时>对于那些不知道什么 __arlist
是的人:http://bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx
推荐答案
您需要使用 C 风格的调用约定 - 其他(包括默认的 Stdecl)不支持可变参数:
You need to use the C-style calling convention - the others (including the default Stdecl) don't support varargs:
[DllImport("foo/bar.dll", EntryPoint = "test",
CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int __unmanaged__test(byte* buffer, __arglist);
另一个棘手的部分是 __arglist(...)
是一个编译时功能 - 它只是为其每个参数"生成(虚拟)堆栈推送.这意味着您不能将它与编译时未知的参数一起使用 - 在您的示例代码中,您只是尝试创建一个输入 object[]
的单个参数.
Another tricky part is that __arglist(...)
is a compile-time feature - it simply generates a (virtual) stack push for each of its "arguments". This means that you can't use it with arguments not known at compile-time - in your sample code, you're simply attempting to make a single argument, typed object[]
.
构建辅助反射方法并不太难 - 请参阅通过 DynamicMethod 调用 varargs 方法 举例.我无法对此进行测试,但我猜可以使用 Expression
轻松构建此代码 - 如果您不必传递那个 byte*
,那就是(做你真的必须这样做吗?传递byte[]
也能正常工作).
Building the helper reflection methods isn't too hard - see Calling varargs method via DynamicMethod for an example. I cannot test this, but I'd guess Expression
could be used to build this code easily - if you didn't have to pass that byte*
, that is (do you really have to? passing byte[]
could work just as well).
这篇关于如何调用/调用“__arglist"功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!