我有这个旧的C ++ COM组件。我采用了最新的代码库,构建了它,发现其中一个属性已成为小写。例如,在预编译的dll中,我有一个属性“Type”,但是当从源代码构建它时,它被称为“类型”。 idl显示该属性被称为“Type”。那么可能会发生什么呢?
答案 0 :(得分:4)
COM不区分大小写,因此库的符号表中只有一个条目符号“type
”。放入符号表的版本是编译器遇到的第一个版本。
微软的advice on the matter只是:
在引入新标识符时,请确保IDL文件中不存在相同的名称。
您应该坚持使用IDL中的Type
或type
,以获得一致的结果。
答案 1 :(得分:3)
摩擦我的水晶球一段时间之后,它得出结论你使用.NET Tlbimp.exe实用程序将类型库转换为.NET互操作类。它有一个错误,如果类型库中有一个具有相同名称但不同大小写的符号,则会导致标识符大小写错误。就像类型库中早先的方法声明一样,它接受一个名为“type”的参数。类型库其余部分中名为“Type”的任何标识符都将转换为“type”。
该实用程序的改进版本为available here。
答案 2 :(得分:0)
问了该问题将近十年后,我遇到了同样的问题,我想分享自己的解决方案(感谢您帮助我们理解问题)。
首先,我想说我有几个名字,它们的大小写由tlbimp
更改了,并将这些名称的所有实例更改为我期望的IDL中的固定大小写,但固定了一个。我假设该名称(Text
)来自我导入的其他IDL。我对更改参数名称之类的解决方案也不满意,因为将来可能会有其他人更改它们。
我找到的解决方案是为我想要的外壳引入一个虚拟接口。我在所有其他import
之前执行过此操作,然后在IDL的library
部分中进行了引用。请注意,这两个细节都是必需的。如果您没有将其放在library
部分中,那么它将被忽略,如果我在library
之后的import
部分的开头定义了它,那就太迟了。
import "oaidl.idl";
import "ocidl.idl";
[
uuid(4EA92D5A-BF84-46C4-AA38-0F7DEADC69B),
helpstring("Ensure that names used in interop have correct casing")
]
interface IAmHack : IUnknown
{
HRESULT Space();
HRESULT The();
HRESULT Final();
HRESULT Frontier();
};
// ...
library MyLib
{
interface IAmHack;
importlib("stdole2.tlb");