如何调用/调用“__arglist"功能? [英] How to P/Invoke "__arglist" function?

查看:73
本文介绍了如何调用/调用“__arglist"功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:
我用 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,我必须在调用之前将其转换为 __arglistC++-函数.


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆