背景:
我用 C++ 编写了以下函数:
extern "C" __declspec(dllexport) int test(const char*, ...);
我使用 P/Invoke 从 C# 调用它:
[DllImport("foo/bar.dll", EntryPoint = "test")]
public static unsafe extern int __unmanaged__test(byte* buffer, __arglist);
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.
我已尝试以下操作,但它返回编译器错误:
unsafe {
byte[] buffer = ....
object[] args = ....
// ....
fixed (byte* ptr = buffer)
return __unmanaged__test(ptr, __arglist(args)); // <--ERROR
}
有谁知道解决这个问题的方法吗?
for those who do not know what __arlist
is:
http://bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx http://bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx
您需要使用 C 风格的调用约定 - 其他调用约定(包括默认的 Stdecl)不支持可变参数:
[DllImport("foo/bar.dll", EntryPoint = "test",
CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int __unmanaged__test(byte* buffer, __arglist);
另一个棘手的部分是__arglist(...)
是一个编译时功能 - 它只是为其每个“参数”生成一个(虚拟)堆栈推送。这意味着您不能将它与编译时未知的参数一起使用 - 在示例代码中,您只是尝试创建单个参数,键入object[]
.
构建辅助反射方法并不太难 - 请参阅通过 DynamicMethod 调用 varargs 方法 https://stackoverflow.com/questions/29458616/calling-varargs-method-via-dynamicmethod举个例子。我无法测试这个,但我猜Expression
可以用来轻松构建此代码 - 如果您不必通过它byte*
,也就是说(你really必须?通过byte[]
也可以工作)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)