排除x64 com互操作编组问题 [英] Troubleshooting an x64 com interop marshaling issue

查看:103
本文介绍了排除x64 com互操作编组问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C + + COM服务器,我最近重新编译为64位。这个COM服务器有一个方法,它包含一个struct参数,该参数包含一些int和一个BSTR和另一个结构。现在,我试图从一个64位.Net C#应用程序调用此COM服务器。我可以成功加载我的COM服务器,并调用此方法,只要我不尝试填充任何字符串参数。如果我尝试在int成员中传递有效的值,它们最终在COM对象实现结束的时候损坏。看起来好像结构被封送的方式是错误的。这个代码在32位应用程序中工作得很好。

I have a C++ COM Server which I have recently recompiled to 64 bit. This COM server has a method that contains a struct parameter which contains some ints and a BSTR and another structure. Now, I am trying to call this COM server from a 64 bit .Net C# application. I can successfully load my COM server and call this method as long as I don't try to populate any of the string parameters. If I try to pass valid values in the int members, they end up corrupted by the time the end up at the COM object implementation. It appears as though the way the structure is marshaled is just wrong. This code worked just fine in 32 bit applications.

以下是在C ++端定义idl的一般方式:(忽略goofy typedefs, )

The following is the general way the idl is defined on the C++ side: (ignore the goofy typedefs, it's some legacy code)

[helpstring("method Method1")] HRESULT Method1([in] STRUCT1* pStruct, [in, out] DWORD* inparm1, [out]USHORT* outparm2);


typedef struct _Struct2
{
    USHORT  p1;
    BSTR  s1;
    BSTR  s2;
    BSTR  s3;
    BSTR  s4;
    DWORD       p2;
    DWORD       p3;
} STRUCT2;


typedef struct _Struct1
{
    DWORD p1;
    DWORD p2;
    BSTR s1;
    BOOL p3;
    STRUCT2 struct2;
}STRUCT1;

尝试填充STRUCT2中的成员会导致未定义的行为和崩溃。任何人都可以看到为什么这将是一个问题在64位的32位代码?有没有一些封送魔法我需要发生?此外,我似乎没有工具来解决封送处理问题。

Attempting to populate the members in STRUCT2 causes undefined behavior and crashes. Can anyone see why this would be a problem in 64 bit verses 32 bit code? Is there some marshaling magic I need to make happen? Additionally, I don't seem to have the tools to troubleshoot marshaling issues. Any suggestions on a good way to troubleshoot what the marshaler is doing under the covers?

推荐答案

结构是COM的Achilles脚跟。结构的成员的实际布局高度依赖于编译器。他们不支持COM自动化很长一段时间,直到他们想出了IRecordInfo黑客。

A struct is COM's Achilles heel. The actual layout of the members of the struct is highly compiler dependent. They were not support in COM automation for quite a while until they came up with the IRecordInfo hack. Not getting used here.

在非托管代码中,#pragma pack指令非常重要。对于类型库,midl.exe的/ pack参数是必不可少的。如果它不是8或你不使用64位版本的midl,那么你肯定会有这种问题。 BSTR成员是抛弃它们的,它们是32位或64位指针,取决于位数。对于32位版本的midl,以4的倍数对齐,对于64位版本,以8的倍数对齐。你可以通过传递/ pack 4,只要结构不包含任何双打拯救它。但是首先尝试64位版本的midl.exe。或者摆脱结构并用接口指针替换它们,这是真正的修复。

In unmanaged code, the #pragma pack directive is very important. For type libraries, the /pack argument to midl.exe is essential. If it isn't 8 or you don't use the 64-bit version of midl then you'll definitely have this kind of problem. The BSTR members are the ones that throw it off, they are either 32-bit or 64-bit pointers, depending on the bitness. And align on a multiple of 4 for the 32-bit version of midl, a multiple of 8 for the 64-bit version. You can possible rescue it by passing /pack 4, as long as the struct doesn't contain any doubles. But try the 64-bit version of midl.exe first. Or get rid of structs and replace them with interface pointers, that's the real fix.

这篇关于排除x64 com互操作编组问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆