我有一个32位DLL,旨在通过com模型和相关的tlb文件进行访问。
DLL似乎是x86。
有没有办法从x64程序访问这种DLL? tlb文件x86 / x64是否不可知?
我问,因为有些功能似乎有效,有些则崩溃了,并且有些功能崩溃了,并且有些功能崩溃了,并且其他功能崩溃了。
。。。。。- 编辑 -
由于OEM部分的错误而导致缺少装配体。
答案 0 :(得分:4)
在大多数情况下,类型库肯定是平台无关的。你在微软发布的Windows编程中遇到的任何一个都是。在.NET中最明显的是,编写可以在32位或64位模式下运行的代码非常简单,由AnyCPU平台目标公开。在Microsoft.Office.Interop中使用interop类或编写在Office程序中运行的扩展名都没有什么特别之处,您可以使用完全相同的类型库。
但是,当您使用由程序员创建的类型库时,这并不总是能够很好地工作,而程序员从不认为它可以在64位代码上工作。最典型的问题是由方法参数引起的,这些参数实际上是引擎盖下的指针,但是扁平化为整数类型, long 是典型的选择。这些指针值在64位模式下为64位宽,当您尝试将它们填充为32位整数时会出现异常。 HANDLE值就是一个很好的例子。
到目前为止,最臭名昭着的哎呀是微软的哎呀。 ADO的类型库被破坏,这是一个广泛用于与dbase引擎通信的数据库提供程序库。他们对Windows 7 SP1进行了一次重大改变,当程序员在该操作系统中构建程序并发现它不再适用于旧版本的Windows时,这一变化会引起广泛的痛苦。那个oops是另一种方式,一种在64位操作系统上应该是32位但在64位操作系统上被宣布为64位的类型。当您拥有Windows SDK版本8,adoint_Backcompat.h头文件,ADO_LONGPTR类型时,您可以看到此oops。在adoint.h中替换为 long 。
最好与原始程序员合作以解决这个问题。或者,为了利用COM代理,当从64位进程调用时,它们可以在进程外运行32位代码。
答案 1 :(得分:2)
类型库在SYSKIND enumeration中包含x86 vs x64标志。实际上它甚至支持16位Windows。它可以使用ITypeLib::GetLibAttr method来读取,如下所示:
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
CComPtr<ITypeLib> tlb;
LoadTypeLib(L"C:\\myPath\\MyFile.tlb", &tlb);
TLIBATTR *patt;
tlb->GetLibAttr(&patt);
switch(patt->syskind)
{
case SYSKIND::SYS_WIN64:
printf("WIN64");
break;
case SYSKIND::SYS_WIN32:
printf("WIN32");
break;
case SYSKIND::SYS_WIN16:
printf("WIN16");
break;
}
tlb->ReleaseTLibAttr(patt);
CoUninitialize();
}
注意SYSKIND不是标志,它是枚举,你没有“任何CPU”值。
答案 2 :(得分:1)
已经很长时间但我认为正确答案是'它取决于'。有些东西可能会透明处理,有些则不会。我的猜测是,大多数时候会有一些特定于平台的位数,但是对此有更多了解的人可能会纠正我。
尝试这篇文章关于将midl(用于生成com类型库的语言)移植到64位。 http://msdn.microsoft.com/en-us/library/ms810720.aspx
但实际上你的问题不是tlb。这只是一堆类型描述符。问题是在dll中实现这些类型。你不能将32位dll加载到64位进程中。 Can I load a 32 bit DLL into a 64 bit process on Windows?
一种可能的解决方案,如果您无法移植dll,涉及代理32位进程和进程间通信 http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/