How to P/Invoke “__arglist” function?

别说谁变了你拦得住时间么 提交于 2021-02-10 15:11:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!