2009-12-10 141 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',創建了相應託管類型的實例,將它們排列在對象數組中,並將它們傳遞給具有不變參數數量的託管方法。