2009-12-10 137 views
1

与调用参数变量数A .NET函数,我想调用C#函数的参数变量数:从非托管代码

void f1(object arg1, params object[] argsRest); 

从非托管,具有可变参数的C函数,它包装F1。

这怎么可能achived?

回答

1

选自C你需要通过你的阵列的长度作为参数,以C#,这样就可以再封的指针阵列成C#阵列。我不认为你可以直接使用该函数签名从C

0

params object[]基本上只是一个数组,所以把它当作阵列。

1

暴露你的管理功能,您将需要编写充当桥梁的混合模式DLL(你应该阅读MSDN this文章作为背景。)

你的C++ - CLI桥DLL将包含类似的代码以下...

#include <cstdarg> 

extern "C" { 
    __declspec(dllexport) void f1wrapper(void *arg1, int nargs, ...) 
    { 
     array<Object^>^ managedArgs = gcnew array<Object^>(nargs); 
     va_list args; 
     va_start(args, nargs); 
     for (int _i = 0; _i < nargs; ++_i) 
     { 
      managedArgs[_i] = ???; // <- you need to translate args 
     } 
     va_end(args); 

     // Call your function 
     Object^ managedArg1 = ???; // <- translate arg1 
     f1(managedArg1, managedArgs); 
    } 
} 

然后,您链接混合模式DLL并从您的C代码中调用f1wrapper(...)。不完整,但应为您提供足够的实验基础。

0

谢谢,我已经实现了这一点。

在C功能:excuting期间

void UnmanagedClass::foo(int i, char *message, ...); 

,变量“i”和消息将被放置在堆栈,然后附加参数数组的地址。

我在一个CLR项目中混合了非托管/托管代码,具有可变数量参数的函数将被编译为非托管函数(here)。这就是为什么我做了一个桥梁类的成员函数:

void ManagedClass::foo(int i, char * message, unsigned int *params); 

和实施:

void UnmanagedClass::foo(int i, char *message, ...) { 
    unsigned int *p = (unsigned int*) &message; 
    p++; 
    ManagedClass::foo(i, message, (unsigned int) p); 
} 

,我并不需要的参数数量,因为“消息”是携带数字信息和printf时尚方式中的参数类型。

这样,在'ManagedClass :: foo()'函数中,我分析了数组'p',创建了相应托管类型的实例,将它们排列在对象数组中,并将它们传递给具有不变参数数量的托管方法。