作者:朱金燦
來源: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++接口示例。
