故障排除64 COM互操作封送处理问题 [英] Troubleshooting an x64 com interop marshaling issue

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

问题描述

我有一个C ++ COM服务器这是我最近重新编译为64位。此COM服务器都有一个包含其中包含了一些整数和BSTR和其他结构的结构参数的方法。现在,我试图打电话从一个64位的.Net C#应用程序这个COM服务器。我可以成功加载我的COM服务器,只要我不尝试填充任何字符串参数,调用此方法。如果我尝试在INT成员通过有效的价值观,他们结束的时候结束了在COM对象实现损坏。看起来好像结构编组的方式是错误的。这code的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.

以下是一般方式IDL是在C ++侧限定:(忽略高飞的typedef,它的一些遗留$ C $三)

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位code的一个问题?有一些编组魔法我需要怎样呢?此外,我似乎没有足够的工具来解决编组的问题。在一个很好的方式有什么建议来解决什么编组是做在幕后?

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的阿喀琉斯之踵。该结构的成员的实际布局是高度依赖编译器。他们没有在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.

在非托管code,使用#pragma pack指令是非常重要的。对于类型库中,/包参数MIDL.EXE是必不可少的。如果不是8,或者不使用64位版本的MIDL,那么你就肯定有这样那样的问题。 BSTR的成员是把它掉的,他们是32位或64位的指针,这取决于位数。和对准上的4的32位版本MIDL,8为64位版本的倍数的整数倍。通过传递/包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.

这篇关于故障排除64 COM互操作封送处理问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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