如何使用C++/CLI包装器将变量参数从托管传递到非托管
How do I pass variable arguments from managed to unmanaged with a C++/CLI Wrapper?
要在托管域中实现params(变量参数)功能,我们在c++/cli中执行以下操作,例如:
funcManaged(int n, ...array<int>^ variableParams)
我对如何将其传递给接受变量参数的非托管域感到困惑。
funcUnmanaged(int n, ...)
我试图传入数组,但结果很糟糕(访问违规、垃圾数据等)。
//where unmanagedVariableParamsArray is an int array
funcUnmanaged(int n, unmanagedVariableParamsArray);
参考资料建议创建一个va_list并将其传递给
vFuncUnmanaged(int n, va_list vl)
但是,我如何在c++/cli域中创建va_list以接受variableParams?重构遗留的非托管代码库不是一个理想的解决方案。
如果你真的非常绝望,那么这并非不可能。变量函数只能由C代码调用,并且该调用必须由C编译器生成。让我们举一个例子:
#include <stdarg.h>
#include <stdio.h>
#pragma unmanaged
void variadic(int n, ...) {
va_list marker;
va_start(marker, n);
while (n--) {
printf("%dn", va_arg(marker, int));
}
}
编译器将把类似variadic(3, 1, 2, 3);
的示例调用转换为:
00D31045 push 3
00D31047 push 2
00D31049 push 1
00D3104B push 3
00D3104D call variadic (0D31000h)
00D31052 add esp,10h
注意参数是如何在堆栈上从左到右传递的。调用后堆栈将被清理。您可以通过使用内联程序集来模拟完全相同的调用模式。看起来是这样的:
void variadicAdapter(int n, int* args) {
// store stack pointer so we can restore it
int espsave;
_asm mov espsave,esp;
// push arguments
for (int ix = n-1; ix >= 0; --ix) {
int value = args[ix];
_asm push value;
}
// make the call
variadic(n);
// fix stack pointer
_asm mov esp,espsave;
}
很直接,只是一些恶作剧来恢复堆栈指针。现在您有了一个适配器函数,可以从托管代码中调用它。您需要一个pin_ptr<>将数组转换为本机指针:
#pragma managed
using namespace System;
int main(array<System::String ^> ^args)
{
array<int>^ arr = gcnew array<int>(3) { 1, 2, 3};
pin_ptr<int> arrp(&arr[0]);
variadicAdapter(arr->Length, arrp);
return 0;
}
工作良好,实际上没有那么危险,在优化的Release构建中进行了测试。注意,如果需要64位代码,您就没有希望实现这一点。
一般建议不推荐:请参阅本文
我建议使用std::vector<int>
来存储参数。
相关文章:
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 扩展可变参数模板中的变量名称
- 在类构造函数中定义结构变量的参数
- 带有整数的变量参数列表
- 转发变量参数列表以模拟 std::thread
- 如何在不传递命令行参数的情况下在 c++ 中设置环境变量
- 存储稍后要转发的变量参数
- C++具有模板成员变量的类. 和参数内存输出
- 我应该如何在没有变量的情况下将相同的参数传递给 CMAKE 中的多个目标?
- 为变量模板的每个参数调用模板函数
- 具有推导参数的模板函数指针数组变量
- 函数参数变量总是需要 & 或 * 运算符吗?
- 为什么 beginthreadex 线程参数变量在父线程中没有更新
- 在 Metal 着色器代码中,如何定义函数的 in/out 参数变量?
- 如何在函数中使用非参数变量?
- 即将将引用作为函数中的参数传递以更改参数变量的值
- 基于不断变化的参数/变量的XML get值
- cocos2d-x v3 CallFunc作为参数/变量如何
- 在编译时使用c++元编程中的运行时参数(变量)
- 我可以返回一个非参数变量吗?