为什么在通话中将char *参数更改为VARIANT_BOOL *?

时间:2018-09-21 21:30:17

标签: import idl

我有一个从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个项目。

问题:

  • 为什么项目B在第一次构建后使用VARIANT_BOOL参数
    但是只有项目B的第二次构建后正确的字符?
  • 为什么A.odl为布尔值指定布尔返回类型 是IsProjectLoaded()方法,但在A.tlb中已将其更改为char?
  • 使用和odl文件与较新的idl格式有关吗? (我对IDL文件的了解还不够,还没有尝试进行转换。)

1 个答案:

答案 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文件。如果我知道了,将做更多的研究并发布答案。