c# - How do I pass variable arguments from managed to unmanaged with a C++/CLI Wrapper? -
to implement params(variable arguments) functionality in managed domain, following in c++/cli such as:
funcmanaged(int n, ...array<int>^ variableparams)
i'm dumbfounded on how pass unmanaged domain takes in variable arguments.
funcunmanaged(int n, ...)
i tried pass array in, ended badly (access violations, junk data, etc).
//where unmanagedvariableparamsarray int array funcunmanaged(int n, unmanagedvariableparamsarray);
resources suggest create va_list , pass around,
vfuncunmanaged(int n, va_list vl)
but how create va_list in c++/cli domain take in variableparams? refactoring legacy unmanaged codebase not desirable solution.
if really, desperate not impossible. variadic function can called c code , call has generated c compiler. let's take example:
#include <stdarg.h> #include <stdio.h> #pragma unmanaged void variadic(int n, ...) { va_list marker; va_start(marker, n); while (n--) { printf("%d\n", va_arg(marker, int)); } }
the compiler turn sample call variadic(3, 1, 2, 3);
into:
00d31045 push 3 00d31047 push 2 00d31049 push 1 00d3104b push 3 00d3104d call variadic (0d31000h) 00d31052 add esp,10h
note how arguments passed on stack, left right. stack gets cleaned after call. can emulate exact same call pattern using inline assembly. looks this:
void variadicadapter(int n, int* args) { // store stack pointer can restore int espsave; _asm mov espsave,esp; // push arguments (int ix = n-1; ix >= 0; --ix) { int value = args[ix]; _asm push value; } // make call variadic(n); // fix stack pointer _asm mov esp,espsave; }
pretty straight forward, shenanigans stack pointer restored. have adapter function can call managed code. you'll need pin_ptr<> turn array native pointer:
#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; }
works , not dangerous, tested in optimized release build. beware have no hope of making work if 64-bit code required.
Comments
Post a Comment