问题
I have a .NET dll which has some interfaces\classes which are exposed to com. during the build procedure a .tlb file is generated and this tlb is referenced by some c++ code. As a result the compiler generates a .tlh file for the tlb.
When I run the build locally one of the properties in one of the interfaces ends up with a corresponding method in the tlh which does not have the same name. The property in the .net code is called PropertyA end up being called get_propertyA, while PropertyB ends up called get_PropertyB. I didn't bat an eyelid when this happened, just used the method as defined in the tlh and assumed everything was hunky dory, however when I comitted these changes the build did not work for anyone else, as the compiler generated properties called get_PropertyA and get_PropertyB (notice case mismatch in propertyA).
The tlb files generated on both machines are identical (according to a hex comparer) and the tlh files are both generated by the same compiler version.
The build procedure creates the tlb by doing: regasm path\to\dll\Mydll.dll -tlb:path\to\output\mydll.tlb
Any ideas why my local version ends up with a property with the incorrect name? Or what I can do to fix it?
UPDATE: I read that tlbexp will use the first version of the string that it finds and that can change with a recompile. Although I'm not using tlbexp, I wondered if that was the problem. I found parameters with the same name as my method (in other methods) but with a lower case letter at the start. So I replaced all of those. Re-built, no change. SO I then renamed my COM method. Re-Built and got the expected missing method errors. Renamed the method back to the original name, and hey presto it seemed fixed. As it now seems to work and I can't get it to fail again I can't try out the suggested solutions, but I like the rename idea in case this happens in the future.
回答1:
You can use the rename attribute for the import to explicitly rename the properties. Say you have propA
that sometimes becomes PropA
and propB
that sometimes becomes PropB
. To always have PropA
and PropB
use rename as follows:
#import <library> rename( "propA", "PropA" ) rename( "propB", "PropB" )
Use this with care - it causes a simple text substitution that works for any identifiers it encounters in the type library. In some cases it can cause hard to debug undesired side effects.
回答2:
I'm having the same problem.
Via another SO question ( https://stackoverflow.com/questions/708721/compare-type-libraries-generated-by-tlbexp ) I found this piece of community content:
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/5003c486-ed3f-4ec8-8398-a1251b0f9e74
Quoting from that content:
In the documentation of tlbexp, there is one useful community content:
http://msdn2.microsoft.com/en-gb/library/hfzzah2c(VS.80).aspx
Quote:
"The reason for the /names option is that type libraries store each identifier in a case-insensitive table. The first case encountered wins. So a class called Monitor might end up being exposed as "monitor" if there's a parameter with such a name encountered first. (And the order in which identifiers are encountered can vary simply by recompiling your assembly!) /names can guarantee stable casing."
The root cause seems to be a bug in the midl, described here:
http://support.microsoft.com/default.aspx?scid=kb;en-us;220137
Quote:
"When there are two identifiers that differ only by case, the case of the second identifier is changed to reflect the case of the first."
So as a solution, I unchecked the option "register for COM interop" in the project settings and added the post-build-steps
"$(DevEnvDir)....\SDK\v2.0\Bin\tlbexp" $(TargetFileName) /names:"$(ProjectDir)Names.txt" %windir%\Microsoft.NET\Framework\v2.0.50727\regasm $(TargetFileName)
The names file contains the entriesthat define how capizalization should be done. In my case it contains only one line:
ID
Best Regards
Bernd Ritter
Using the /names has solved this problem for me.
回答3:
Sanity check: are you absolutely sure the same #import directive is used on both machines? i.e. the same exactly source files being compiled?
Try creating a network share over the directory containing the project and open it on the other machine in order to be 1000% sure these are the same source files being compiled.
Sorry I don't have any more specific suggestions.
来源:https://stackoverflow.com/questions/911461/tlh-generated-on-2-machines-is-different