解决VC2008编译C/C++混合代码出现D8045错误的问题

使用Visual Studio 2008编译VC程序,如果窗体上需要引入一个C#编写的UserControl,那么必须在引入程序的代码*.h文件包含afxwinforms.h文件,比如:

#pragma once
#include <afxwinforms.h>
#using "..\Bin\MyUserControl.dll" // C# UserControl assembly

包含afxwinforms.h必须选择“/clr”选项,即要选中Configuration Properties->General下的“Common Language Runtime Support (/clr)”。

如果这个VC程序是一个ActiveX组件,需要预编译*.idl接口定义文件,那么就需要在源码中包含.idl的预编译结果文件*_i.c,此时编译会产生D8045错误:
cl : Command line error D8045 : cannot compile C file '.\*_i.c' with the /clr option

另外加了“/clr”选项后有几个选项需要对应的修改:
1. C/C++->General下的Debug Information Format只能选“/Zi”,默认“/ZI”会报D8016错误。
2. C/C++->Code Generation下的Basic Runtime Checks只能选Default,默认“/RTC1”也会报D8016错误。

对于D8045错误网上找到原因是必须使用“/TP”选项,在C/C++->Advanced下的Compile As里,默认已经是“/TP”,如果把它改成Default再改回“/TP”,Compile As会变成黑体字,此时编译能成功,但链接时出错:
*.obj : error LNK2020: unresolved token (nnn) IID_Ixxx
原因是*_i.c编译的*.obj里虽然定义有IID_Ixxx但似乎没能链接进工程里,解决办法是先恢复成默认“/TP”选项,需要用记事本等文本编译器打开工程文件*.vcproj,找到Name="VCCLCompilerTool"项,把它下面CompileAs="2"这一行删除然后保存,回到VC工程重新加载,再全编译就会还原成D8045错误。

那么怎么解决掉D8045错误呢,经过对比别人写过成功编译的代码,无意中我右击*_i.c看其属性,发现C/C++->General下的Compile with Common Language Runtime support并不是“/clr”,而是改成了“No xxx”,我也按这个方法改了一下,全编译竟然成功了,看样子是针对性的让*_i.c文件不使用“/clr”选项来解决这个问题的。

2015-09-08 Update: 在Windows XP上编译成功但在Windows 7上编译同样的代码会提示_AFX_TREAD_STATE不匹配的失败信息,解决办法是还原整个工程不需要“/clr”参数然后编译,在提示需要加“/clr”参数的.cpp再按上述.c的方式加上“/clr”即可。

Tags:

Leave a Reply


提醒: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。请务必注意user必须和评论者名相匹配(大小写一致)。