我有一个32位的DLL,可以通过com模型和关联的tlb文件访问。
该DLL似乎是x86。
有什么办法从x64程序访问这种types的DLL? tlb文件x86 / x64是不可知的?
我在问,因为有些function似乎正常工作,其他function崩溃了,而且还有其他的function。
– 编辑 –
由于OEM的错误,出现缺less组件。
在大多数情况下,类型库肯定是平台不可知的。 在微软出货的Windows编程中,大多数人都会遇到这种情况。 在.NET中最容易看到,它使编写可以运行在32位或64位模式下的代码变得非常简单,由AnyCPU平台目标公开。 使用Microsoft.Office.Interop中的interop类或者在Office程序中运行的写扩展名,不需要任何特殊的操作,就可以使用完全相同的类型库。
但是,当您使用由程序员创建的类型库从未考虑过在64位代码上工作时,这并不总是如此。 最典型的麻烦是由方法参数引起的,这些方法参数实际上是引擎盖下的指针,但却是扁平化的整体类型, 长期以来就是典型的选择。 这些指针值在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位代码。
类型库在SYSKIND枚举中包含x86 vs x64标志。 实际上它甚至支持16位Windows。 它可以使用ITypeLib :: GetLibAttr方法读取,如下所示:
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”的值。
这已经很长时间了,但我认为正确的答案是“取决于”。 有些事情可能会被透明地处理,有些则不会。 我的猜测是,大多数时候在那里会有一些特定的平台,但有些人对此更为了解可能会纠正我。
试试这篇关于将midl(用于生成com类型库的语言)移植到64位的文章。 http://msdn.microsoft.com/en-us/library/ms810720.aspx
但是真正的问题不在于tlb。 这只是一个类型描述符。 这个问题将是在DLL中的这些类型的实现。 你不能加载一个64位进程的32位DLL。 我可以在Windows上加载一个32位DLL到64位进程吗?
一个可能的解决方案,如果你无法移植的DLL,涉及代理32位进程和进程间通信http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-码/