1

我有一个 C++ COM 服务器,它用数据填充 C# 调用者的结构。

该结构在 C++ IDL 中定义,如下所示:

interface Icontrol : IDispatch{
    [ 
    uuid(...), 
    version(1.0) ]
    typedef struct testStructure
    { 
        int x;
        int y;
        int z;
        ...
    } testStructure; 

    ...
    [id(9)] HRESULT getStruct([ref,in,out] testStructure * theData);
    ...

然后,在 C# 代码中:

EO_Lib.testStructure test = new EO_Lib.testStructure();
EO_Lib.getStruct(ref test);

通过简单地在 C# 结构中为非 C# 本地字段使用 MarshallAs,我可以使用常规 .DLL 使这项工作没有问题。但我不能让它在 COM .DLL 上工作。我怀疑这是因为我对 IDL 缺乏了解。

我需要做的是用我用适当的 MarshallAs() 信息创建的新 C# 类型调用 getStruct()。我该怎么做呢?

如果有帮助,我正在使用 Visual Studio 2010 MFC/ATL C++ 和 C# .NET 4 Framework。

4

2 回答 2

0

虽然不是该问题的实际解决方案,但以下内容排除了我提出问题的原因。

来自: http: //msdn.microsoft.com/en-us/library/75dwhxf7 (v=vs.100).aspx

从平台调用调用返回的结构必须是 blittable 类型。平台调用不支持非 blittable 结构作为返回类型。

所以基本上,你不能做我想做的事。

如果您忽略 COM 方面,BrokenGlass 的解决方案在这里回答了 convert-one-structure-to-another 问题。

于 2012-08-20T17:58:15.130 回答
0

听起来您正试图从托管方面解决这个问题。不知道有关您的体系结构的许多细节(例如,这是您的 COM 服务器,就像您编写它/拥有代码一样?)我将不得不做出一些假设,以便提供从 C++ 方面接近的任何解决方案,特别是MIDL (IDL) 方面。

您提到了 IDL,据我所知,至少您可以访问生成类型库的 IDL。因此,暂时忘记 CLR(托管)方面的内容,让它在非托管环境 (COM) 中正常工作。

完成后,确定您希望托管客户端的结构看起来像什么。使用该信息,在您的 C++/MIDL 项目中定义一个新类型。如果您的 IDL 没有 ACF(应用程序配置文件)文件,请创建一个(它只是一个名称完全相同但扩展名为“.acf”而不是“.idl”的 IDL 文件。在 ACF 文件中声明一个 user_marshal 类型,将您的 COM 结构映射到您刚刚定义的新“托管友好”结构。像这样:

// ACF file

typedef [user_marshal(testStructure_ForDotNet)] testStructure;

// where testStructure is your "original" struct and "testStructure_ForDotNet" 
// is the one you just defined.

最后,您需要定义转换函数(编组函数)。有关更多信息,请参阅此资源:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa367296(v=vs.85).aspx

无论如何,希望对(任何人)有所帮助。

于 2014-09-24T08:08:52.093 回答