我有一个围绕C#调用的标准C++库的C++-CLR包装器。为了从库接收状态消息,我使用通过Marshal::GetFunctionPointerForDelegate在C++代码中分配给回调的委托(delegate)。
这花了我很多时间才能开始工作,而且我非常非常亲密(我认为)。调用了C#委托(delegate),但字符串未正确通过边界传递。
当我从C++代码调用TakesCallback(“Test String”)时,我只是在C#函数中得到了垃圾。
---原始的C++类和回调函数-
class Solver
{
private:
std::string TakesCallback(const std::string message)
{
return cb(message);
}
public:
// Declare an unmanaged function type that takes a string
typedef std::string (__stdcall* ANSWERCB)(const std::string);
ANSWERCB cb;
};
---从托管包装器设置回调的功能----
// Set the delegate callback
void ManagedSolver::SetMessageCallback(SendMessageDelegate^ sendMessageDelegate)
{
_sendMessage = sendMessageDelegate;
// Use GetFunctionPointerForDelegate to get the pointer for delegate callback
IntPtr ip = Marshal::GetFunctionPointerForDelegate(sendMessageDelegate);
_solver->cb = static_cast<Solver::ANSWERCB>(ip.ToPointer());
}
---将C#函数传递给C++\CLR包装器SetMessageCallBack ----
private void Message(string message)
{
XtraMessageBox.Show(message, "Done", MessageBoxButtons.OK);
}
最佳答案
C++ std::string
和.NET System::String
不可互换。 C#不能使用第一个, native C++代码不能使用第二个。您需要一个C++/CLI函数,该函数接受std::string
并在调用委托(delegate)之前将其转换为System::String^
。