hr1 = 0x80020009 发生意外。

本文详细介绍了在Win7 64位系统下使用VS2008将WPS2013文档转换为PDF格式时遇到的错误,并通过调整VARIANT类型的值成功解决问题的过程。同时,深入解释了VARIANT类型中iVal和lVal的区别及其在COM调用中的应用。

环境:win7 64位,vs2008,wps2013

错误代码:

BOOL CWPSOper::ConvertToPdf(IDispatch* lpDoc,_bstr_t sTargetPath)
{
	CComVariant varParams[15];
        varParams[1].vt = VT_I4;
        varParams[1].iVal = 1;
        varParams[0].vt = VT_BYREF|*/VT_VARIANT;
        varParams[0].pvarVal = &(varParams[1]);
        CComVariant varRet, varRet2, varRet3;
        HRESULT hr1 = GetProperty(lpDoc, L"Application", &varRet);
        HRESULT hr2 = GetProperty(varRet.pdispVal, L"Documents", &varRet2);
        hr1 = InvokeN(varRet2.pdispVal, L"Item", varParams, 1, &varRet3);
}

HRESULT InvokeN(IDispatch *pDisp, LPCOLESTR lpszName, VARIANT *varParams, int nParams, VARIANT *pvarRet)
{   
    if(pDisp == NULL)
        return E_FAIL;   

    HRESULT hr;   
    DISPID dispid;   

    hr = pDisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpszName, 1, LOCALE_USER_DEFAULT, &dispid);   
    if (SUCCEEDED(hr))
    {   
        DISPPARAMS dispparams = { varParams, NULL, nParams, 0};   
        return pDisp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);   

    }
    return hr;   

} 

解决:

而通过vc添加typelib中类,通过wpsapi.dll生成CDocument,CDocuments,CApplication三个类,然后调试跟到oledisp2.cpp中的

 SCODE sc = m_lpDispatch->Invoke(dwDispID, IID_NULL, 0, wFlags,
        &dispparams, pvarResult, &excepInfo, &nArgErr);

发现dispparams的iVal值为0x00000001

而我的错误代码中iVal值为0xcccc0001

然后源代码改为varParams[1].lVal = 0x00000001;

结果就返回正确值S_OK了

原因:显而易见,variant是union类型, iVal只是lVal中的后半段内存,但是com处理invoke调用应该统一使用long,不会又是long又是int


module digital_clock( input clk, // 1Hz主时钟输入 input CLR, // 异步清零信号(高电平有效) output [3:0] sec1, sec0, // 秒十位和个位(BCD码) output [3:0] min1, min0, // 分十位和个位 output [3:0] hr1, hr0 // 时十位和个位 ); // 内部信号 wire clk_sec, clk_min, clk_hr; // 秒、分、时时钟信号 wire carry_sec, carry_min; // 进位信号 // 秒计时模块(60进制) second_counter sec_counter ( .clk(clk), // 1Hz时钟 .CLR(CLR), // 清零信号 .sec1(sec1), // 秒十位 .sec0(sec0), // 秒个位 .carry(carry_sec) // 进位到分 ); // 分计时模块(60进制) minute_counter min_counter ( .clk(carry_sec), // 秒进位信号 .CLR(CLR), // 清零信号 .min1(min1), // 分十位 .min0(min0), // 分个位 .carry(carry_min) // 进位到时 ); // 小时计时模块(24进制) hour_counter hr_counter ( .clk(carry_min), // 分进位信号 .CLR(CLR), // 清零信号 .hr1(hr1), // 时十位 .hr0(hr0) // 时个位 ); endmodule // 秒计数器模块(60进制) module second_counter( input clk, input CLR, output reg [3:0] sec1, output reg [3:0] sec0, output reg carry ); always @(posedge clk or posedge CLR) begin if (CLR) begin sec1 <= 4'd0; sec0 <= 4'd0; carry <= 1'b0; end else begin carry <= 1'b0; // 默认无进位 if (sec0 == 4'd9) begin sec0 <= 4'd0; if (sec1 == 4'd5) begin sec1 <= 4'd0; carry <= 1'b1; // 产生进位 end else begin sec1 <= sec1 + 1; end end else begin sec0 <= sec0 + 1; end end end endmodule // 分计数器模块(60进制) module minute_counter( input clk, input CLR, output reg [3:0] min1, output reg [3:0] min0, output reg carry ); always @(posedge clk or posedge CLR) begin if (CLR) begin min1 <= 4'd0; min0 <= 4'd0; carry <= 1'b0; end else begin carry <= 1'b0; // 默认无进位 if (min0 == 4'd9) begin min0 <= 4'd0; if (min1 == 4'd5) begin min1 <= 4'd0; carry <= 1'b1; // 产生进位 end else begin min1 <= min1 + 1; end end else begin min0 <= min0 + 1; end end end endmodule // 小时计数器模块(24进制) module hour_counter( input clk, input CLR, output reg [3:0] hr1, output reg [3:0] hr0 ); always @(posedge clk or posedge CLR) begin if (CLR) begin hr1 <= 4'd0; hr0 <= 4'd0; end else begin if (hr0 == 4'd9) begin hr0 <= 4'd0; hr1 <= hr1 + 1; end else if (hr1 == 4'd2 && hr0 == 4'd3) begin // 达到23:59:59后归零 hr1 <= 4'd0; hr0 <= 4'd0; end else begin hr0 <= hr0 + 1; end end end endmodule 要求整点报时,整电时产生对应个数的脉冲
最新发布
05-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值