如何使用C++/CLIWrapper将可变参数从托管传递到非托管?为了在托管域中实现参数(可变参数)功能,我们在c++/cli中执行以下操作,例如:funcManaged(intn,...array^variableParams)损失。funcUnmanaged(intn,...)我试图传入一个数组,但结果很糟糕(访问冲突、垃圾数据等)。//其中unmanagedVariableParamsArray是一个int数组funcUnmanaged(intn,unmanagedVariableParamsArray);该资源建议创建一个va_list并将其传递给vFuncUnmanaged(intn,va_??listvl)但是如何在c++/cli域中创建一个va_list以接受variableParams?重构遗留的非托管代码库并不是一个理想的解决方案。如果你真的非常非常绝望,那也不是不可能。Variadic函数只能由C代码调用,并且调用必须由C编译器生成。让我们举个例子:#include#include#pragmaunmanagedvoidvariadic(intn,...){va_listmarker;va_start(标记,n);while(n--){printf("%dn",va_??arg(marker,int));}}编译器将调用类似variadic(3,1,2,3)的示例;调用可变参数(3、1、2、3);into:00D31045push300D31047push200D31049push100D3104Bpush300D3104Dcallvariadic(0D31000h)00D31052addesp,10h注意参数是如何从堆栈传递到堆栈的,从左到右。调用结束后,清理栈。您可以使用内联汇编模拟完全相同的调用模式。看起来像这样:voidvariadicAdapter(intn,int*args){//存储堆栈指针以便我们可以恢复它intespsave;_asmmovespsave,esp;//推送参数for(intix=n-1;ix>=0;--ix){intvalue=args[ix];_asm推送值;}//进行调用variadic(n);//修复堆栈指针_asmmovesp,espsave;非常简单,只是一些恶作剧,用于恢复堆栈指针。现在您有一个可以从托管代码调用的适配器函数。您需要一个pin_ptr将数组转换为本机指针:#pragmamanagedusingnamespaceSystem;intmain(array^args){array^arr=gcnewarray(3){1,2,3};pin_ptrarrp(&arr[0]);variadicAdapter(arr->长度,arrp);返回0;在优化版本构建中测试,效果很好,实际上并不危险。请注意,如果您需要64位代码,则无法执行此操作。一般的建议是不要:看这篇文章我推荐使用std::vector来存储参数。以上就是C#学习教程:HowtouseC++/CLIWrappertopassvariableparametersfrommanagedtounmanaged?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
