问题
Background:
I have written the following function in C++:
extern "C" __declspec(dllexport) int test(const char*, ...);
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);
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?
for those who do not know what
__arlist
is: http://bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx
回答1:
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);
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[]
.
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).
回答2:
The comment Luuan wrote (see here) had the solution I needed:
quote:
If you need to build __arglist dynamically (that is, you don't know the types and amount of arguments in advance), you'll probably have to use reflection.
See stackoverflow.com/questions/29458616/… for example
来源:https://stackoverflow.com/questions/32175822/how-to-p-invoke-arglist-function