【发布时间】:2011-04-26 00:03:08
【问题描述】:
我有一个围绕从 C# 调用的标准 C++ 库的 C++-CLR 包装器。为了从库中接收状态消息,我使用通过 Marshal::GetFunctionPointerForDelegate 分配给 C++ 代码中的回调的委托。
我花了很长时间才开始工作,而且我非常非常接近(我认为)。调用了 C# 委托,但字符串未正确跨边界传递。
当我从 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++? (我认为)Visual Studio 2003 不再支持 C++ 的托管扩展。C++/CLI 是它的替代品,它是一种完全不同的语言......
-
嗨,比利,对不起,你当然是对的。我的包装器是围绕标准 C++ 库的 C++/CLR。我已经更新了标题和正文。
-
好的,我已经解决了,std::string 不能与互操作一起使用,因为这里声明了多种实现stackoverflow.com/questions/874551/stdstring-in-c,只要 StackOverflow 允许我,我就会回来回答这个问题到。
-
传递 message.c_str() 代替,与默认编组兼容。
-
谢谢汉斯,这对我有用。
标签: c# visual-c++ callback c++-cli interop