2009-05-26 30 views
6

我有一个.NET DLL,它有一些接口\类,暴露给com。在生成过程中生成一个.tlb文件,这个tlb被一些C++代码引用。结果编译器为tlb生成一个.tlh文件。.tlh在2台机器上生成是不同的

当我在本地运行构建时,其中一个接口的属性中的一个属性以tlh中的相应方法结束,而该名称不具有相同的名称。 .net代码中的属性称为PropertyA,最终被称为get_propertyA,而PropertyB最终称为get_PropertyB。发生这种情况时,我并没有眨眼睛,只是使用了tlh中定义的方法,并假设所有内容都是hunky dory,但是当我对这些更改进行评估时,构建对其他人无效,因为编译器生成了名为get_PropertyA的属性,并且get_PropertyB(注意propertyA中的大小写不匹配)。

在两台机器上生成的tlb文件是相同的(根据十六进制比较器),并且tlh文件都由相同的编译器版本生成。

的构建过程做创建TLB:regasm路径\到\ DLL \ MYDLL.DLL -tlb:路径\为\输出\ mydll.tlb

为什么我的本地版本与属性结束了任何想法名称不正确?或者我能做些什么来解决它?

更新:我读了tlbexp将使用它找到的字符串的第一个版本,并且可以通过重新编译进行更改。虽然我没有使用tlbexp,但我想知道这是否是问题所在。我找到了与我的方法相同的参数(在其他方法中),但在开始时使用小写字母。所以我取代了所有这些。重建,没有变化。所以我然后重新命名我的COM方法。重新构建并获得了预期缺失的方法错误。将该方法重命名为原始名称,并且它似乎是固定的。因为它现在似乎工作,我不能再次失败,我不能尝试建议的解决方案,但我喜欢重命名的想法,以防将来发生这种情况。

+0

使用“重命名”解决方法时要小心 - 它可以像简单的文本替换一样工作,并且有时可能会导致出现奇怪的结果。我已经更新了大纲的答案。 – sharptooth 2009-05-28 09:01:55

+0

谢谢你的抬头。如果问题出现,我会记住这一点。 – 2009-05-28 10:43:59

回答

4

您可以使用重命名属性为导入显式重命名属性。假设你有propA有时变成PropApropB,有时变成PropB。总是有PropAPropB使用如下命名

#import <library> rename("propA", "PropA") rename("propB", "PropB") 

使用此小心 - 它会导致一个简单的文本替换,对于它在类型库中遇到任何标识的作品。在某些情况下,它可能很难调试不希望的副作用。

0

完整性检查:你确定在两台机器上都使用了相同的#import指令吗?即正在编译的源文件是否相同?

尝试在包含项目的目录上创建网络共享,并在另一台机器上打开它,以确保这些文件与编译的源文件相同。

对不起,我没有任何更具体的建议。

+0

是的,我们已经通过了健康检查。正在编译相同的文件,我们检查了CVS版本号。并且我们检查了中间步骤产生了正确的文件(tlb文件是相同的),并且在这个版本中新引入(重命名)了属性,所以它们出现的事实表明它正在使用正确的源。 .. – 2009-05-26 16:17:25

+0

你可以发布你正在使用的#import行吗? – 2009-05-26 19:54:26

4

我遇到同样的问题。

通过另一个SO问题(https://stackoverflow.com/questions/708721/compare-type-libraries-generated-by-tlbexp)我发现了这片社区内容:

http://social.msdn.microsoft.com/Forums/en-US/clr/thread/5003c486-ed3f-4ec8-8398-a1251b0f9e74

从内容引用:

在tlbexp的文档,有一个有用的社区内容:

http://msdn2.microsoft.com/en-gb/library/hfzzah2c(VS.80).aspx

Quote:

“/名称选项的原因是,类型库将每个标识符存储在不区分大小写的表中。第一例遇到胜利。因此,如果有一个名字遇到第一个参数,那么称为Monitor的类可能最终会暴露为“monitor”。 (!并在其中遇到标识符的顺序可以通过重新编译程序集只是会发生变化)/名称可以保证稳定的外壳”

根本原因似乎是在MIDL中的错误,说明如下:

http://support.microsoft.com/default.aspx?scid=kb;en-us;220137

引用:

“当存在只有大小写不同的两个标识符,所述第二标识符的情况下被改变以反映所述第一的情况下”

因此,作为一种解决方案,我unch在项目设置中添加了“注册COM互操作”选项,并添加了后建立步骤

“$(DevEnvDir).... \ SDK \ v2.0 \ Bin \ tlbexp”$(TargetFileName)/名称:“$(ProjectDir)Names.txt” %windir%\ Microsoft.NET \ Framework \ v2.0.50727 \ regasm $(TargetFileName)

名称文件包含定义应如何执行capizalization的entriest。在我的情况下,它仅包含一个行:

ID

问候

贝恩德·里特尔

使用/名称已经解决了这个问题对我来说。

相关问题