【问题标题】:How to return struct or ptr to struct from ActiveX C++ class method如何从 ActiveX C++ 类方法返回 struct 或 ptr 到 struct
【发布时间】:2012-05-30 23:19:38
【问题描述】:

我有一个最初用 MSVC++ 6.0 编写的非托管 C++ DLL。它有几个类和一些独立的 C 函数,我需要从 C# .NET 4.0 调用它们。我在这方面有过几次错误的开始。我知道有几种方法可以做到这一点(转换为 COM、MC++ 包装器、PInvoke),但尚不清楚哪种方法最直接。我目前的方法是将 C++ DLL 转换为 ActiveX 控件。我遇到的问题是,当尝试在 VS 2010 C++ ActiveX 项目中重新创建方法时,类向导不允许任何返回类型,除了基本类型、CString 或指向 CWnd 的指针。如何返回结构的副本或指向结构的指针?似乎也不可能作为参数返回,因为方法参数的类型与返回类型具有相同的类型限制。

【问题讨论】:

    标签: c++ com struct activex marshalling


    【解决方案1】:

    您不应该将非托管数据返回到托管代码(或任何代码)。如果您的 ActiveX 类正在分配此内存,则您的 ActiveX 类负责取消分配。

    解决这个问题的一个常用方法是有一个方法,它返回一个 HRESULT 并接收具有数据大小的原始数据,或者如果你想要更托管的东西,它可以接收一个安全的字节数组(这可以是映射到托管代码中的 byte[])。

    在您的方法实现中,您可以使用结构的数据覆盖数组。

    回到托管代码中,您需要将结构编组为字节数组,以便将其传递给您的新方法。 Marshal.StructureToPtr 方法可能有助于完成这项任务。

    为了给你的类添加一个接收指针作为参数的方法,你可以使用你的activex控件默认界面的“添加方法”上下文菜单选项。见下图:

    【讨论】:

    • 感谢您的帮助。但是,在 Wikipedia 中查找 HRESULT 似乎只是一个 32 位错误/状态代码返回。如何使用它返回一组原始字节和大小?
    • 问题是,您不会返回原始数据,您将在托管代码中创建数据并将其作为普通参数传递给您的非托管代码,以便您可以在上面写下你的结果数据。您可以将原始数据视为一张空白纸,您将把纸传递给您的 GetCurrentLookupItem 方法,然后您将在此方法中填写纸。如果我有时间,我明天会尝试包含一些代码。
    • 好的,这是有道理的,但我仍然想知道如何在 ActiveX 控件中创建一个方法,如果唯一允许的参数类型可以接收由 ActiveX 方法填充的空原始数据缓冲区类向导中的基本标量类型(BYTE、FLOAT、INT、UINT、HRESULT 等)。我是否使用 HRESULT 参数并将其转换为指向结构的指针或类似的东西?
    • 您应该看到更多参数类型的选项,您还应该有 LPBYTE、PBYTE、SAFEARRAY、VARIANT 等。您还应该有 IDispatch*、IUKNOWN*,并且应该能够指定每个参数作为 [out] 或 [in]。
    • 那些其他类型没有出现在类向导对话框中,无论是返回类型还是参数类型。唯一允许的类型是与原始问题一起发布的屏幕截图中显示的类型,即:bool、char double、float HRESULT int、long long double、short、unsigned char、unsigned int、unsigned long、void DWORD、WORD、BYTE、FLOAT , INT, UINT, LRESULT CString, CString^, CWnd * 我正在运行 Visual Studio 2010 专业版 10.0.40219.1 SP1 Rel,项目类型是 C++ Active X 控件
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2021-07-07
    • 2014-12-07
    • 2021-01-02
    • 2012-03-28
    • 2020-02-16
    • 2022-12-10
    相关资源
    最近更新 更多