6

我有一个 32 位 DLL,旨在通过 com 模型和关联的 tlb 文件访问。

DLL 似乎是 x86。

有没有办法从 x64 程序访问这种 DLL?tlb 文件是否与 x86/x64 无关?

我之所以问,是因为有些功能似乎可以工作,有些则崩溃,并且 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̶s̶。

- 编辑 -

由于 OEM 方面的错误,出现缺少装配。

4

3 回答 3

5

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.

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.

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.

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.

于 2013-05-21T09:29:30.330 回答
3

类型库在SYSKIND 枚举中确实包含 x86 与 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”这样的值。

于 2013-05-21T08:46:18.513 回答
2

已经很长时间了,但我认为正确的答案是“视情况而定”。有些事情可以透明地处理,有些则不会。我的猜测是,大多数时候那里会有一些特定于平台的位,但对此更了解的人可能会纠正我。

试试这篇关于将 midl(用于生成 com 类型库的语言)移植到 64 位的文章。http://msdn.microsoft.com/en-us/library/ms810720.aspx

但实际上你的问题不在于 tlb。那只是一堆类型的描述符。问题将是这些类型在 dll 中的实现。您不能将 32 位 dll 加载到 64 位进程中。 我可以在 Windows 上将 32 位 DLL 加载到 64 位进程中吗?

一个可能的解决方案,如果你不能移植 dll,涉及代理 32 位进程和进程间通信 http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-代码/

于 2013-05-21T03:25:09.893 回答