用VS2012新建C++工程都预定义了宏__cplusplus,所以引用到的都是C++的定义。但是要用C实现的话,一般都是也就不是C++的了。比如以下代码:

#undef  INTERFACE
#define INTERFACE IExample
DECLARE_INTERFACE_ (INTERFACE, IUnknown)
{
STDMETHOD (QueryInterface) (THIS_ REFIID, void **) PURE;
STDMETHOD_ (ULONG, AddRef) (THIS) PURE;
STDMETHOD_ (ULONG, Release) (THIS) PURE;
STDMETHOD (SetString) (THIS_ char *) PURE;
STDMETHOD (GetString) (THIS_ char *, DWORD) PURE;
};

C版本的宏DECLARE_INTERFACE_和C++版本的宏就不是同一个东西。在C中没有class的概念,所以这里使用了struct,而且在C版本中在宏中已经设置了Vtbl,这是最大的区别。C版本的DECLARE_INTERFACE_:

#define DECLARE_INTERFACE_(iface, baseiface)    DECLARE_INTERFACE(iface)

#define DECLARE_INTERFACE(iface)    typedef interface iface { \
struct iface##Vtbl FAR* lpVtbl; \
} iface; \
typedef struct iface##Vtbl iface##Vtbl; \
struct iface##Vtbl

C++版本的DECLARE_INTERFACE_:

#define DECLARE_INTERFACE_(iface, baseiface)            interface DECLSPEC_NOVTABLE iface : public baseiface

但奇怪的是__cplusplus没有undef的情况下,也可以声明IExampleVtbl对象,但就是会有红色的波浪线,提示是未定义的标识符,同时能顺利编译通过。而这点也是困惑我的地方。按道理,如果没有undef __cplusplus的话,cl应该执行的是C++版本中的宏。但是其中有一个重要点是文件是以c结尾。对于cl是否是根据文件后缀来选择编译还是根据其他规则也就不得而知了,因为对cl没有太多了解。至少如果文件是以c为后缀的话,编译器能够选择正确的宏版本来执行代码这点是没错的。

因为在编译器中没有undef __cplusplus,宏的定义是直接定位到对应的C++版本的,而这会干扰到我们正常的代码编写,如果我们忘记了的话。比如这个宏:

REFCLSID

C++版本:

#define REFCLSID const IID &

C版本:

#define REFCLSID const IID * __MIDL_CONST

就明显有本质的区别。我们编写的是C代码,但是调到定义处看的定义却是C++版本。一般会出现类似类型不匹配的情况。这点是尤其应该注意的。

VS2012中使用纯C实现COM的小问题的更多相关文章

  1. VS2012中丢失ArcGIS模板的解决方法

    VS2012中丢失ArcGIS模板的解决方法 由于ArcGIS10.0(for .NET)默认是用VS2010作为开发工具的,所以在先安装VS2012后装ArcGIS10.0 桌面版及ArcObjec ...

  2. VS2012中数据库架构的比较

    在进行项目进行开发或维护时,经常会改动使用的数据库,或增加.修改字段,或加表,改存储过程等,而且会出现多个类似的数据库同时在用(比如过个类似的项目,要使用稍有不同的数据库),这个时候就可能需要进行数据 ...

  3. Vs2012 中使用itoa

    自己在写程序的时候经常用到保存大量的图片,从而对其编号,所以要把整型转换成字符型. 通常自己定义string,而字符使用char[],把整形转换成char类型,然后和string类型相加,但是在VS2 ...

  4. 在Vs2012 中使用SQL Server 2012 Express LocalDB打开Sqlserver2012数据库

    http://www.cnblogs.com/huangtailang/p/4221164.html 背景:个人电脑中使用的是VS2012,数据库为2008R2,最近需要打开一个SqlServer20 ...

  5. 在VS2012中采用C++中调用DLL中的函数 (4)

    这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人 ...

  6. textContent、innerText的用法,在文档中插入纯文本

    有时候需要查询纯文本形式的元素内容,或者在文档中插入纯文本.标准的方法是用Node的textContent属性来实现: var para = document.getElementsByTagName ...

  7. [COCOS2DX]官网helloworld在VS2012中的部署

    VS2012.JDK.Eclipse(和adt插件)之类的基本安装这里直接略过. 以下为对cocos2dx 3.5版本在VS2012中部署的摸索: 开源项目“愤怒的小鸟”原来设置: .;..\Clas ...

  8. ASP.NET CompareValidator 控件在VS2012中出错的问题

    CompareValidator 控件用于将由用户输入到输入控件的值与输入到其他输入控件的值或常数值进行比较. -------如果输入控件为空,则不会调用任何验证函数,并且验证将成功.使用 Requi ...

  9. vs2012中使用localdb实例还原一个sql server 2008r2版本的数据库

    use localdb sometime is easy than sql server ,and always use visual studio make you stupid. vs2012中还 ...

随机推荐

  1. poj1417 true liars(并查集 + DP)详解

    这个题做了两天了.首先用并查集分类是明白的, 不过判断是否情况唯一刚开始用的是搜索.总是超时. 后来看别人的结题报告, 才恍然大悟判断唯一得用DP. 题目大意: 一共有p1+p2个人,分成两组,一组p ...

  2. c语言学习之基础知识点介绍(十二):结构体的介绍

    一.结构体的介绍 /* 语法: struct 结构体名{ 成员列表; }; 切记切记有分号! 说明:成员列表就是指你要保存哪些类型的数据. 注意:上面的语法只是定义一个新的类型,而这个类型叫做结构体类 ...

  3. effective c++(04)之对象使用前初始化

    对于内置类型以外的初始化责任落在构造函数身上.如下: class PhoneNumber{}; class ABEntry{ public: ABEntry( const string& na ...

  4. 怎样区分JQuery对象和Dom对象 常用的写法

    第一步,http://www.k99k.com/jQuery_getting_started.html 第二步,新手先仔细得全部看一遍jQuery的选择器,很重要!!! (http://shawphy ...

  5. OC - 12.NSURLRequest与NSURLConnection

    ##NSURLRequest NSURLRequest封装了一次网络请求所需要的数据,主要封装了以下信息: 请求路径(URL) 请求方法(GET或POST) 请求头 请求体 超时参数 NSURLReq ...

  6. javascript 将多维数组转换为一维数组

    /** * 2013年9月去面试的时候,有面试过这样子一道题目: * 题目是这样子的:将一个多维数组转换成一维数组并返回该数组,类似 * [1,2,3,[4,5,6,[7,8]],9]转换后为:[1, ...

  7. [转] jQuery按键响应事件keypress对应的按键编码keycode

    原文地址:http://blog.csdn.net/chenhj1988918/article/details/7534922 keypress  api 文档:http://api.jquery.c ...

  8. Python之实现一个简易计算器

    自己动手写计算器 一.功能分析 用户输入一个类似这样 3*( 4+ 50 )-(( 100 + 40 )*5/2- 3*2* 2/4+9)*((( 3 + 4)-4)-4) 这样的表达式,假设表达式里 ...

  9. 使用python发送简单的邮件

    from:http://blog.csdn.net/zhaoweikid/article/details/125898 前些时间,论坛上有人讨论怎么用python发送需要认证的邮件,我在我的FreeB ...

  10. windows+apache2.2.9+php5.4.41+mysql安装

    安装Apache(D盘根目录下) (1)打开D:\Apache24\conf下httpd.conf 文件,用记事本打开编辑作如下修改并保存. 第37行ServerRoot "c:/Apach ...