作者:朱金燦
來源:http://blog.csdn.net/clever101
現在有這樣一種情景,假如C#調用C++接口需要返回一個字符串。因為字符串是不定長的,因此傳遞一個定長的字符串進去是不合適的。
因此需要一種間接的做法,簡單來說就是C#定義一個創建空字符串的接口,傳遞這個接口指針給C++模塊,然后在C++模塊中調用這個C#接口創建一個空的字符串接口。然后在傳遞字符串時先調用這個C#接口創建一個空字符串,然后再填充字符串。具體的代碼如何:
#region 本段代碼可放在其他位置,但保證系統啟動后能初始化 static protected StringHelper swigStringHelper = new StringHelper(); // 系統初始化時先調用 protected class StringHelper { public delegate string StringDelegate(string message); static StringDelegate stringDelegate = new StringDelegate(CreateString); // AlgoDemo為C++模塊,RegisterStringCallback為創建字符串的注冊回調函數 [DllImport("AlgoDemo", EntryPoint = "RegisterStringCallback")] public static extern void RegisterStringCallback(StringDelegate stringDelegate); static string CreateString(string cString) { return cString; } static StringHelper() { RegisterStringCallback(stringDelegate); } } // C#程序調用處 private void btnExcute_Click(object sender, EventArgs e) { string strOut = ""; string strResult = Algo.ExcuteAlgo("C#調用C++測試!", 0, ref strOut); MessageBox.Show(strOut); }
// C++模塊的注冊回調函數 typedef char * (__stdcall* StringHelperCallback)(const char *); static StringHelperCallback g_csharp_string_callback = NULL; extern "C" __declspec(dllexport) void RegisterStringCallback(StringHelperCallback callback) { g_csharp_string_callback = callback; } // C++接口 char* ExcuteAlgo(const char* strFileName,int arg0,char** strOut) { char* result; TestAlgo algo; std::string strInput(strFileName); std::string strResult = algo.DoSomething(strFileName,arg0); // 此處需要注意,由調用方開辟空間 result = "中文測試!!"; std::string strTemp = "輸出字符串測試。。。"; for(int i=0;i<500;i++) { strTemp += "多加一點數據...!!"; } if(NULL==g_csharp_string_callback) return NULL; // 把C++字符串傳遞給空的C#字符串 *strOut = g_csharp_string_callback(strTemp.c_str()); return result; }
代碼示例工程見: C#調用C++接口示例。