【问题标题】:How would I call a legacy C++ DLL interface method, with params BSTR* and BSTR** from C#如何使用 C# 中的参数 BSTR* 和 BSTR** 调用旧版 C++ DLL 接口方法
【发布时间】:2017-03-17 05:25:22
【问题描述】:

开发者们好日子

我已经在互联网上搜索了 2 天,以了解如何做我需要的事情,并且我尝试了很多示例,但都没有成功。但是,这并不意味着我覆盖了所有网站 - 我认为我一只眼睛失明,另一只眼睛看不到。

无论如何,我收到了一张纸,上面有 COM 自动化接口定义,并被要求开发一个 C# 应用程序来相应地利用接口和回调。

所以,从简单开始(或者我认为)- C++ 方法签名是:

STDMETHODIMP CSimpleChatServer::CallMe(BSTR clientName, BSTR** returnMessage)

接口签名为:

HRESULT _stdcall CallMe([in] BSTR clientName, [in] BSTR** helloMessage);

我需要从 C# 调用它 - 我已经为 ISimpleChatServer 建立了接口;因此,我正在尝试的代码调用是这样的。

string rtrnMsg = string.Empty; ImySimpleCom.CallMe("Robert", rtrnMsg)

由于签名是 [in],我在尝试访问受保护的内存时遇到异常。

现在,我相信它需要一个 IntPtr 作为第二个参数;然而,我所有的尝试都失败了。

请记住,我无法更改库 - 它是一个“原样”的遗留界面,我们需要使用一段时间,并且提供者没有人相应地更新它(事实上我认为他们没有人来处理它)。

欢迎任何帮助。

此致,罗伯特 S.

【问题讨论】:

  • 您如何为ImySimpleCom 创建代码?您是使用 p/invoke 还是使用 .NET 的内置 COM 功能?
  • SimpleCOMLib.SimpleChatServer mySimpleCom = new SimpleCOMLib.SimpleChatServer(); SimpleCOMLib.ISimpleChatServer ImySimpleCom = (SimpleCOMLib.ISimpleChatServer)mySimpleCom;
  • 我不是说你是如何创建一个新实例的,我是说你是如何为类生成代码本身的。我更新了我之前的评论,但您可能需要刷新。
  • 您对 CallMe 函数的描述包含两个 [in] 但您说要返回 helloMessage... 在这种情况下声明它 [out,retval] 并获取返回值。
  • 我很抱歉 - 我想,也许我不明白(我很感谢你的关注),我使用的是 VS2012,基本上使用的是 C# 的内置模板。在这个例子中,我创建了一个测试表单应用程序,我使用了一个类模板,然后我添加了上面的代码。该表单有一个简单的“Do It All”按钮,它触发类的实例化,因此子序列行如下所示。表单有一个文本框来简单地显示结果。

标签: c# c++ interface com bstr


【解决方案1】:

.idl 中的接口应该是

HRESULT _stdcall CallMe([in] BSTR clientName, 
                        [out,retval] BSTR** helloMessage);

所以只取 CallMe 的返回值

SimpleChatServer mySimpleCom = new SimpleChatServer();   
string helloMessage = mySimpleCom( clientName );

当您在 C++/C 方法中返回字符串时,您使用 SysAllocString 分配并通过分配给 helloMessage 将其返回给调用者。

*helloMessage = SysAllocString(L"MyString");

以上所有内容均假设您已在 C# 项目中引用了 COM 服务器。

我现在更仔细地阅读了您的问题,所以您不能更改“旧”代码?如果它说

HRESULT _stdcall CallMe([in] BSTR clientName, 
                        [in] BSTR** helloMessage);

那么它应该被改变,因为那是不正确的。

【讨论】:

  • 嘿嘿 - 我就是这么想的,我告诉他们,他们的回答是“就是这样”。好的,从技术上讲 - 正如我所想的那样,为了让我得到他们试图在第二个参数中传回的任何内容,他们需要更正一些东西,以便它具有 [out, retval] 参数属性。
  • @RobertSpringer 如果它保持为[in][in]
【解决方案2】:

谢谢大家和安德烈斯

我终于与客户取得了联系,是的,他们提供的信息不正确,并且 [in] 属性应该是 [out,retval] 以允许回传字符串 - 一旦他们更正了,一切顺利。

非常感谢大家 - 谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 2011-07-03
    • 2017-01-20
    • 2015-03-21
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    相关资源
    最近更新 更多