纯C语言集成Excel遇到的问题及解决

本文介绍如何在Visual Studio 2008环境下使用纯C语言调用Excel 2007的功能,包括获取Excel对象接口文件、处理COM对象操作及解决常见错误。

C语言集成Excel遇到的问题及解决

Kagula

2010-12-30

简介

对在VisualStudio2008+SP1环境下纯C语言调用Excel12(Excel2007)功能实现过程中碰到的问题做下简单总结。

正文

参考[1]和参考[3]的编程思路用纯C语言调用Excel2007( OLE对象)

第一步:我们要利用OLE ViewerMIDL工具得到Excel对象接口的C语言头文件及源文件。

[S1-1]Visual Studio2008中自带Windows SDK,我这里用到了6.0A版本的Win SDK,启动[你的Win SDK安装目录]/Microsoft SDKs/Windows/v6.0A/bin/OleView.Exe

打开Type Libraries中的Microsoft Excel 12.0 Object Library,在新出现的窗口中你可以看到IDL语言源文件内容把它复制拷贝出来(注意不要使用Toolbar中的Save按钮来保存文件,用该方式保存的文件是GBK编码很难编辑和使用)。我这里把这个文件命令为excel.idl

[S1-2]使用快捷菜单“Microsoft Visual Studio 2008/Visual Studio Tools/Visual Studio 2008 Command Prompt”,在新弹出的窗口中使用MIDL excel.idl命令,当然会弹出大量的错误。因为很多类型的定义依赖于mso.idl

在你系统的Program Files目录下的Common Files/Microsoft Shared目录中搜索mso.dll利用OLE Viewer工具得到mso.idl

[S1-3]把缺少的类型定义复制到excel.idl文件中。注意这里有些定义没找到不是不存在,而是被放到了文件尾部,这里建议你使用前向引用,特别是coclass的定义,你不能移动它原来的位置否则MIDL为报MIDL9008号错误。

[S1-4]修改excel.idl直到midl excel.idl不在出现error,这时使用midl /h excel12.h excel.idl命令,我们就得到了excel12.h excel12_i.c excel12.tlb文件。

第二步:现在我们要利用生成的代码实现对Excel OLE对象的操作

[S2-1]引入excel12.h文件后报出大量的错误,修改代码直到没有error。对象的定义如果没找到,可以用IDispatch类型代替。在idl源文件dispinterface的定义只会引出IDispatch接口,dispinterface对象中的其它method需要使用Invoke的方式调用。或者使用QueryInterface方式得到它的interface对象,这样就可以使用“宏方式”操作这个对象。

注意源文件头部可能需要加上下面两行代码,第一行表示COM采用C接口,第二行表示COM对象采用宏调用

#define CINTERFACE

#define COBJMACROS

QueryInterface方式调用在Pure C中有两种方式

第一种如下:

HRESULT hr = IUnknown_QueryInterface_Proxy(COM对象指针,&要查询的COM对象的IID,&查询得到的COM对象指针);

hr = IUnknown_Release_Proxy(要释放的COM对象指针);

在文件头加上下面这段代码

#pragma comment(lib, "rpcrt4.lib")

否则你会找不到这两个函数的实现。如果调用成功hr的值为S_OK

第二种方式:

COM对象->lpVtbl->QueryInterface(COM对象,&要查询的COM对象的IID,&查询得到的COM对象指针);

第二种方式只适合从interface中引出的COM对象,这类对象支持VTBL(虚函数列表)

在这种方式下你也可以直接使用“宏方式”,示例代码如下

IRange_QueryInterface(COM对象,&要查询的COM对象的IID,&查询得到的COM对象指针);

其中上面的IRangeCOM对象的类型名称。

[S2-2]COM对象方法的调用

参考[2]手动对COM对象(IDispatch接口)操作

先使用GetIDsOfNames方法再使用Invoke。这里需要注意入口参数的设置。不需要入口参数直接可以使用下面这个变量传入

DISPPARAMS disp_params = {NULL,NULL,0,0};

如果需要传入一个字符串变量,参考下面的这段代码

VARIANT vBSTR;

vBSTR.vt = VT_BSTR;

vBSTR.bstrVal = SysAllocString(L"这是第一行第一列");

DISPPARAMS disp_params = {NULL,NULL,0,0};

DISPID dispidNamed = DISPID_PROPERTYPUT;

disp_params.cArgs = 1;

disp_params.rgvarg = &vBSTR;

disp_params.cNamedArgs = 1;

disp_params.rgdispidNamedArgs = &dispidNamed;

字符串类型的变量用好后记得使用下面的语句释放

SysFreeString(vBSTR.bstrVal);

如果需要传入两个字符串变量,参考下面的这段代码

VARIANT vRanges[2]

disp_params.cArgs = 2;

disp_params.rgvarg = vRanges;

参考

[1]C语言调用COM组件(ADO)

http://www.rupeng.com/forum/thread-16350-1-1.html

[2] Excel writing and reading with pure c API

http://blog.youkuaiyun.com/fanchuan0077/archive/2009/09/14/4552117.aspx

[3] C实现ExcelOLE自动化

http://hi.baidu.com/mettlesome/blog/item/d655ea173cd98809c83d6ddf.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值