【发布时间】:2013-03-16 03:06:03
【问题描述】:
我想通过 CLI/C++ 从 C++ 调用 C# 函数。
C#代码
private string _text = " ";
public void setText(string text)
{
// _text = text;
_text = "HI World";
}
理想情况下,setText 应该只有注释行。 _text = "HI World" 就是一个例子。
public string getText()
{
return _text;
}
C++/CLI 代码
标题:
gcroot<Bridge> _managedObject;
virtual void setText(std::string text);
virtual std::string getText();
CPP 文件
std::string CStringBridge::getText()
{
// _managedObject = gcnew Bridge(); 返回 (marshal_as(_managedObject->getText())); }
void CStringBridge::setText(std::string text)
{
// _managedObject = gcnew Bridge(); _managedObject->setText(gcnew System::String(text.c_str())); }
IStringBridgeWrapper* IStringBridgeWrapper::CreateInstance(void)
{
return ((IStringBridgeWrapper *)new CStringBridge());
}
注意:当我使用以下代码时
virtual void setText(System::String^ text);
virtual System::String^ getText();
我收到以下错误 3395
*__declspec(dllexport) 不能应用于具有 __clrcall 调用约定的函数*
,所以我坚持使用 std::string
当我使用 C++/CLI 代码中的库并从我的 C++ 程序中调用时,应该打印“Hi World”;而是什么都没有打印出来
C++ 控制台应用程序
IStringBridgeWrapper *pBridge = IStringBridgeWrapper::CreateInstance();
pBridge->setText(std::string("I am here"));
pBridge->getText();
我认为字符串没有被正确传递。
任何解决它的想法都会受到赞赏。
编辑
我在 cmets 之后更新了代码,但没有任何显示。
gcroot 创建句柄,但不为其分配内存。但是由于 Bridge 没有分配内存,因此应用程序无法运行。我的代码在本文的同一行中 - http://www.codeproject.com/Articles/10020/Using-managed-code-in-an-unmanaged-application。
【问题讨论】:
-
为什么要在 CPP/CLI
getText函数中创建Bridge的新实例,如果我理解正确,那不会重置 C# 类中的_text对象吗? -
您正在 getText 和 setText 函数中创建新的 Bridge 实例。这当然行不通,因为您刚刚创建了对象,getText 将始终返回一个空字符串。您的包装器需要一个 Bridge 实例作为成员。查看您最喜欢的关于封装的 C++ 语言书籍。
-
我也在想这可能是个问题。谢谢你指点。我有 gcroot
_managedObject ;我应该用那个吗? (请参阅编辑后的帖子)您对我在 setText 中传递的字符串有何看法;我应该 gcnew 吗? -
如何在控制台上显示文本?您是否调试过代码并确认返回的字符串实际上是空的?
-
@RedSerpent 。我确实放置了一些 Console.Writeline 语句来检查流程,并且流程符合预期 - C++ 到 C++/CLI 到 C#。