【问题标题】:How to call a COM function that returns a string when called from C#, Java如何调用从 C#、Java 调用时返回字符串的 COM 函数
【发布时间】:2023-03-14 10:10:01
【问题描述】:

问题陈述:

  1. 向现有的 COM 库添加一个返回字符串的函数。
  2. C# 应用程序使用 COM 互操作版本使用 COM 库(使用 tblimp 生成的 .net 运行时程序集)

到目前为止,我已经尝试了以下变体:

C++ 端代码:

变体 1:HRESULT GetString([out] BSTR* string);

变体 2:HRESULT GetString([out,retval] BSTR* string);

C# 端代码:

string str;

变体 1:GetString(out str);

变体 2:str = GetString();

但是两者都会引发Attempt to read/write memory 或类似措辞的异常。

我在正确的轨道上吗?或者是否有一些编组限制导致引发异常(例如在进行内存管理时等)?我无法在网上找到关于哪种方法最适合上述情况的明确解释,因此请寻求帮助。

更进一步的计划是这个 COM 函数将从 Java 应用程序中调用。

注意:请忽略函数语法,可能包含错误。当从 C++ COM 库中调用这两种变体时,COM 中实现的代码可以正常工作,但对于 C# 则失败,如上所述。

【问题讨论】:

  • 你的C++代码错了,从这里看不到。
  • 什么意思?我不担心语法,而是这里的方法。

标签: c# c++ com com-interop


【解决方案1】:

我怀疑您的 C++ 代码有问题。假设您使用 ATL,返回字符串的一种方法是这样做:

HRESULT GetString([out,retval] BSTR* string)
{
    const char* ReturnString = "A string to return";
    *string = CComBSTR( ReturnString ).Detach();
    return S_OK;
}

ReturnString 可以替换为您希望返回的任何字符串。

【讨论】:

  • 这个函数签名与我上面提到的 C++ 代码的变体 [2] 有何不同?我正在 COM 端进行分配,预计 C# 会释放它。
  • 函数签名没有什么不同,但我认为问题不在于你的函数签名。如果您发布您的 C++ 代码,那么我或其他人也许能够告诉您确切的问题。
  • 我明白你的意思。我观察到该函数在从 COM 库调用或使用 C# 中的 dll 导入时可以完美运行。
  • 补充一下,代码也和你上面写的差不多。我不明白为什么从互操作调用相同的函数会导致异常?我是否应该从 C# 传递字符串长度和分配的缓冲区以由 C++ 写入,以便更轻松地进行内存管理?我希望避免这种方法,因为那时该函数不能再返回可变长度的字符串。
  • 我怀疑该函数因互操作而失败,因为您在 C++ GetString 函数中分配内存或类似内容略有错误,这在从 C# 调用时会导致问题。但是,当从 C++ 调用时,它可能会起作用,因为没有任何东西会自动处理释放和分配内存,因此您不会遇到问题。我不建议从 C# 传递分配的缓冲区,这听起来是一个非常糟糕的解决方案。但是,除非您编辑您的帖子以包含 GetString 的 C++ 实现,否则我真的无法再帮助您了。
【解决方案2】:

你还问过 java...

你必须使用 JNI。您将函数声明为 native,然后生成包装代码,在其中您可以访问任何您想要的内容,例如.NET 库或 COM。

看看这里: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html

【讨论】:

    猜你喜欢
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 2021-04-14
    • 1970-01-01
    • 2011-10-14
    相关资源
    最近更新 更多