我有一个从VC6转换而来的VS2017解决方案。它有42个C ++项目,可以无错误地进行编译,但有一个异常异常。
项目A是具有COM接口的.exe项目。该接口在项目A的A.odl文件中定义。生成项目A时,它将生成预期的A.tlb文件。 .exe和.tlb文件都已移动到公共Bin目录。项目B也是一个.exe项目,该项目使用项目A的接口和#import“ .. \ Bin \ A.tlb”指令。
当我清洁解决方案时,删除公用Bin目录,然后重新生成,项目B失败并显示以下消息:
HRESULT A :: IA :: raw_IsSameProject(BSTR,VARIANT_BOOL *);无法将参数2从'char *'转换为'VARIANT_BOOL *'
产生错误的实际代码是:
char chResult = 0;
if (S_OK != pIA->raw_IsProjectLoaded(&chResult)) ...
在这一点上,如果我仅构建项目B,则错误消失。
这是项目A的第二个构建之前各个文件的相关内容。(文件A.tlh和A.tli位于项目B的Debug目录中)
A.odl boolean IsProjectLoaded();
A.tlb char IsProjectLoaded();
A.tlh VARIANT_BOOL IsProjectLoaded();
HRESULT raw_IsProjectLoaded (VARIANT_BOOL * _result = 0);
A.tli inline VARIANT_BOOL ITndrtData::IsProjectLoaded ( ) {
VARIANT_BOOL _result = 0;
_com_dispatch_method(...);
return _result;
}
inline HRESULT ITndrtData::raw_IsProjectLoaded (VARIANT_BOOL* _pr){
return _com_dispatch_raw_method(...);
}
第二次仅构建项目B后:
A.tlh char IsProjectLoaded();
HRESULT raw_IsProjectLoaded (char * _result = 0);
A.tli inline VARIANT_BOOL ITndrtData::IsProjectLoaded ( ) {
char _result = 0;
_com_dispatch_method(...);
return _result;
}
inline HRESULT ITndrtData::raw_IsProjectLoaded ( char * _presult ) {
return _com_dispatch_raw_method(...);
}
在项目B的第二次构建之后,VARIANT_BOOL参数更改为预期的char。 _com_dispatch方法中的相关类型参数也从VT_BOOL *更改为char *。
项目B引用了项目A。在正在构建的42个项目中,项目A是要构建的第12个项目,项目B是第21个项目。
问题:
答案 0 :(得分:0)
发布问题后,我仔细检查了构建输出并发现了问题。在此解决方案的项目中,有几个循环引用。为了解决这个问题,创建了几个Circular_Build项目,这些项目仅使用MIDL来编译项目的IDL或ODL文件来创建项目的.tlb文件。项目A有一个Circular_Build项目,我以为我已经删除了。在查看生成输出时,我注意到在构建项目A和B之后,仍在构建Circular_Build项目。删除此Circular_Build项目可以消除异常。
这仍然是一个问题,为什么A的Circular_Build项目创建一个使用char *参数的.tlb文件,而A的普通版本创建使用VARIANT_BOOL *参数的.tlb文件。如果我知道了,将做更多的研究并发布答案。