I have a 32bit DLL that is designed to be accessed through the com model and the associated tlb file.
我有一个32位DLL,旨在通过com模型和相关的tlb文件进行访问。
The DLL appears to be x86.
DLL似乎是x86。
Is there any way to access this kind of DLL from an x64 program? Are tlb files x86/x64 agnostic?
有没有办法从x64程序访问这种DLL? tlb文件x86 / x64是否不可知?
I am asking because some functions appear to work, others crash, and o̶t̶h̶e̶r̶s̶ ̶a̶r̶e̶ ̶m̶i̶s̶s̶i̶n̶g̶ ̶c̶o̶m̶p̶a̶r̶e̶d̶ ̶t̶o̶ ̶t̶h̶e̶ ̶.̶n̶e̶t̶ ̶a̶s̶s̶e̶m̶b̶l̶i̶e̶s̶ .
我问,因为有些功能似乎有效,有些则崩溃了,并且有些功能崩溃了,并且有些功能崩溃了,并且发生了故障。
--Edit--
- 编辑 -
Missing assemblies appear due to error on the part of the OEM.
由于OEM部分的错误,会出现缺少的程序集。
3 个解决方案
#1
4
Type libraries were certainly intended to be platform agnostic in most cases. Most any one you'd encounter in Windows programming that were shipped by Microsoft are. Most visible in .NET which makes it very simple to write code that can run in either 32-bit or 64-bit mode, exposed by the AnyCPU platform target. Nothing special is needed to either use the interop classes in Microsoft.Office.Interop or write extensions that run inside an Office program, you use the exact same type libraries.
在大多数情况下,类型库肯定是平台不可知的。在微软发布的Windows编程中遇到的大多数都是。在.NET中最明显的是,编写可以在32位或64位模式下运行的代码非常简单,由AnyCPU平台目标公开。要么在Microsoft.Office.Interop中使用互操作类或编写在Office程序中运行的扩展,都不需要特殊的东西,就可以使用完全相同的类型库。
But that doesn't always work out so well when you use a type library created by a programmer that never considered it to work on 64-bit code. The most typical trouble is caused by method arguments that are actually pointers under the hood but flattened to a integral type, long being the typical choice. These pointer values are 64-bit wide in 64-bit mode and misbehave when you try to stuff them into a 32-bit integer. HANDLE values are a good example.
但是,当您使用由程序员创建的类型库时,这并不总能很好地解决,因为程序员从未认为它可以在64位代码上运行。最典型的问题是由方法参数引起的,这些参数实际上是引擎盖下的指针,但是扁平化为整数类型,长期以来是典型的选择。这些指针值在64位模式下为64位宽,当您尝试将它们填充为32位整数时会出现异常。 HANDLE值是一个很好的例子。
By far the most notorious oops is a Microsoft one. The type library for ADO was broken, a database provider library that's widely used to talk to dbase engines. They took a breaking change in Windows 7 SP1, a change that cause widespread misery when programmers built their programs in that operating system and found out it no longer worked on older versions of Windows. That oops went the other way, a type that was supposed to be 32-bit on 64-bit operating systems but was declared to be 64-bit on a 64-bit OS. You can see this oops when you have the Windows SDK version 8, adoint_Backcompat.h header file, the ADO_LONGPTR type. Replaced by long in adoint.h.
到目前为止,最臭名昭着的哎呀是微软的哎呀。 ADO的类型库被破坏,这是一个广泛用于与dbase引擎通信的数据库提供程序库。他们对Windows 7 SP1进行了重大改变,当程序员在该操作系统中构建程序并发现它不再适用于旧版本的Windows时,这一变化会引起广泛的痛苦。那个oops是另一种方式,一种在64位操作系统上应该是32位但在64位操作系统上被宣布为64位的类型。如果您拥有Windows SDK版本8,adoint_Backcompat.h头文件,ADO_LONGPTR类型,则可以看到此oops。在adoint.h中替换为long。
Best to work with the original programmer to get this sorted out. Or to take advantage of COM surrogates, they can run 32-bit code out-of-process when called from a 64-bit process.
最好与原始程序员一起解决这个问题。或者,为了利用COM代理,当从64位进程调用时,它们可以在进程外运行32位代码。
#2
2
Type Library do contain a x86 vs x64 flag in the SYSKIND enumeration. In fact it even supports 16 bits Windows. It can be read using the ITypeLib::GetLibAttr method, something like this:
类型库在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();
}
Note SYSKIND is not a flags, it's an enum, you don't have something like "any CPU" value.
注意SYSKIND不是标志,它是枚举,你没有“任何CPU”值。
#3
1
It has been a long time but I think the correct answer is 'it depends'. Some things may be handled transparently some will not. My guess is that most of the time there will be some platform specific bitness in there, but somebody more knowledgeable on that may correct me.
这已经很久了,但我认为正确答案是'它取决于'。有些东西可能会透明处理,有些则不会。我的猜测是,大多数时候会有一些特定于平台的位数,但是对此有更多了解的人可能会纠正我。
Try this article about porting midl (the language used to generate com type libs) to 64bit. http://msdn.microsoft.com/en-us/library/ms810720.aspx
试试这篇关于将midl(用于生成com类型库的语言)移植到64位的文章。 http://msdn.microsoft.com/en-us/library/ms810720.aspx
But really your problem isn't the tlb. That's just a bunch type descriptors. The issue is going to be the implementation of those types in the dll. You cant load a 32bit dll into a 64bit process. Can I load a 32 bit DLL into a 64 bit process on Windows?
但实际上你的问题不是tlb。那只是一堆类型描述符。问题是在dll中实现这些类型。你不能将32位dll加载到64位进程中。我可以在Windows上将32位DLL加载到64位进程中吗?
A possible solution, if you cant port the dll, involving a surrogate 32bit process and inter process communication http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
一个可能的解决方案,如果你不能移植dll,涉及代理32位进程和进程间通信http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-码/
#1
4
Type libraries were certainly intended to be platform agnostic in most cases. Most any one you'd encounter in Windows programming that were shipped by Microsoft are. Most visible in .NET which makes it very simple to write code that can run in either 32-bit or 64-bit mode, exposed by the AnyCPU platform target. Nothing special is needed to either use the interop classes in Microsoft.Office.Interop or write extensions that run inside an Office program, you use the exact same type libraries.
在大多数情况下,类型库肯定是平台不可知的。在微软发布的Windows编程中遇到的大多数都是。在.NET中最明显的是,编写可以在32位或64位模式下运行的代码非常简单,由AnyCPU平台目标公开。要么在Microsoft.Office.Interop中使用互操作类或编写在Office程序中运行的扩展,都不需要特殊的东西,就可以使用完全相同的类型库。
But that doesn't always work out so well when you use a type library created by a programmer that never considered it to work on 64-bit code. The most typical trouble is caused by method arguments that are actually pointers under the hood but flattened to a integral type, long being the typical choice. These pointer values are 64-bit wide in 64-bit mode and misbehave when you try to stuff them into a 32-bit integer. HANDLE values are a good example.
但是,当您使用由程序员创建的类型库时,这并不总能很好地解决,因为程序员从未认为它可以在64位代码上运行。最典型的问题是由方法参数引起的,这些参数实际上是引擎盖下的指针,但是扁平化为整数类型,长期以来是典型的选择。这些指针值在64位模式下为64位宽,当您尝试将它们填充为32位整数时会出现异常。 HANDLE值是一个很好的例子。
By far the most notorious oops is a Microsoft one. The type library for ADO was broken, a database provider library that's widely used to talk to dbase engines. They took a breaking change in Windows 7 SP1, a change that cause widespread misery when programmers built their programs in that operating system and found out it no longer worked on older versions of Windows. That oops went the other way, a type that was supposed to be 32-bit on 64-bit operating systems but was declared to be 64-bit on a 64-bit OS. You can see this oops when you have the Windows SDK version 8, adoint_Backcompat.h header file, the ADO_LONGPTR type. Replaced by long in adoint.h.
到目前为止,最臭名昭着的哎呀是微软的哎呀。 ADO的类型库被破坏,这是一个广泛用于与dbase引擎通信的数据库提供程序库。他们对Windows 7 SP1进行了重大改变,当程序员在该操作系统中构建程序并发现它不再适用于旧版本的Windows时,这一变化会引起广泛的痛苦。那个oops是另一种方式,一种在64位操作系统上应该是32位但在64位操作系统上被宣布为64位的类型。如果您拥有Windows SDK版本8,adoint_Backcompat.h头文件,ADO_LONGPTR类型,则可以看到此oops。在adoint.h中替换为long。
Best to work with the original programmer to get this sorted out. Or to take advantage of COM surrogates, they can run 32-bit code out-of-process when called from a 64-bit process.
最好与原始程序员一起解决这个问题。或者,为了利用COM代理,当从64位进程调用时,它们可以在进程外运行32位代码。
#2
2
Type Library do contain a x86 vs x64 flag in the SYSKIND enumeration. In fact it even supports 16 bits Windows. It can be read using the ITypeLib::GetLibAttr method, something like this:
类型库在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();
}
Note SYSKIND is not a flags, it's an enum, you don't have something like "any CPU" value.
注意SYSKIND不是标志,它是枚举,你没有“任何CPU”值。
#3
1
It has been a long time but I think the correct answer is 'it depends'. Some things may be handled transparently some will not. My guess is that most of the time there will be some platform specific bitness in there, but somebody more knowledgeable on that may correct me.
这已经很久了,但我认为正确答案是'它取决于'。有些东西可能会透明处理,有些则不会。我的猜测是,大多数时候会有一些特定于平台的位数,但是对此有更多了解的人可能会纠正我。
Try this article about porting midl (the language used to generate com type libs) to 64bit. http://msdn.microsoft.com/en-us/library/ms810720.aspx
试试这篇关于将midl(用于生成com类型库的语言)移植到64位的文章。 http://msdn.microsoft.com/en-us/library/ms810720.aspx
But really your problem isn't the tlb. That's just a bunch type descriptors. The issue is going to be the implementation of those types in the dll. You cant load a 32bit dll into a 64bit process. Can I load a 32 bit DLL into a 64 bit process on Windows?
但实际上你的问题不是tlb。那只是一堆类型描述符。问题是在dll中实现这些类型。你不能将32位dll加载到64位进程中。我可以在Windows上将32位DLL加载到64位进程中吗?
A possible solution, if you cant port the dll, involving a surrogate 32bit process and inter process communication http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/
一个可能的解决方案,如果你不能移植dll,涉及代理32位进程和进程间通信http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-码/