对于c++ 调用 IDispatch 问题,用于com包含

nicholascheung 2007-04-16 02:47:02
单位有一个很早以前的 com 用于加密的
但是由于 是用的变体类型 不好,导致是用不方便
下面是定义
interface ICrypt : IDispatch {
[id(0x60020000)]
HRESULT OnStartPage([in] IUnknown* piUnk);
[id(0x60020001)]
HRESULT OnEndPage();
[id(0x00000001), helpstring("method PwdEncode")]
HRESULT PwdEncode(
[in, out] VARIANT* aDst, /*输出加密后字符*/
[in] VARIANT* aSrc, /*需要加密的字符*/
[in] VARIANT* aKey, /*key*/
[out, retval] VARIANT* ret);/*加密后的状态*/

我打算写一个com封装一下.要返回加密后的字符串。把变体的类型写具体
打算把 [in, out] VARIANT* aDst 改成 返回值
把[in] VARIANT* aKey 改成具体的LONG 其他的VARIANT改成BSTR 便于托管代码的调用。

问题是 执行的时候 hr 是成功的。但是 没有取到输出参数的值。
是不是VARIANTARG 没有指定输入参数? ? 一般的写法很少有不是函数返回值的输出参数。

下面是我写的代码 通过IDispatch调用


bool isSuccee=false; //执行成功标志
::CoInitialize( NULL ); // COM 初始化

CLSID clsid; // 通过 ProgID 得到 CLSID
HRESULT hr = ::CLSIDFromProgID( L"util.Crypt.1", &clsid );


IDispatch * pDisp = NULL; // 由 CLSID 启动组件,并得到 IDispatch 指针
hr = ::CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IDispatch, (LPVOID *)&pDisp );

LPOLESTR pwFunName = L"PwdEncode"; // 准备取得 Add 函数的序号 DispID
DISPID dispID; // 取得的序号,准备保存到这里
hr = pDisp->GetIDsOfNames( // 根据函数名,取得序号的函数
IID_NULL,
&pwFunName, // 函数名称的数组
1, // 函数名称数组中的元素个数
LOCALE_SYSTEM_DEFAULT, // 使用系统默认的语言环境
&dispID ); // 返回值
if(SUCCEEDED( hr ))
{
int a=0;
}
else
{
int a=1;
}
VARIANTARG v[3]; // 调用 所需要的参数
CComBSTR bstrVal=L"";
v[0].vt = VT_BSTR; v[0].bstrVal =bstrVal.Copy; // 第二个参数,整数2
v[1].vt = VT_BSTR; v[1].bstrVal = Source; // 第一个参数,整数1
v[2].vt = VT_INT; v[2].lVal = eKey; // 第一个参数,整数1

DISPPARAMS dispParams = { v, NULL, 3, 0 }; // 把参数包装在这个结构中
VARIANT vResult; // 函数返回的计算结果

hr = pDisp->Invoke( // 调用函数
dispID, // 函数由 dispID 指定
IID_NULL,
LOCALE_SYSTEM_DEFAULT, // 使用系统默认的语言环境
DISPATCH_METHOD, // 调用的是方法
&dispParams, // 参数
&vResult, // 返回值
NULL, // 不考虑异常处理
NULL); // 不考虑错误处理
if(FAILED( hr ))
{


}
else
{
isSuccee=true;
*retStr=v[0].bstrVal;
}

pDisp->Release(); // 释放接口指针
::CoUninitialize(); // 释放 COM
if(isSuccee=true)
{
return S_OK;
}
else
{
return S_FALSE;

}


...全文
372 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
nicholascheung 2007-04-18
  • 打赏
  • 举报
回复
呵呵 还是不行 我觉得问题就是出在 看看 下面是 til文件(引用dll生成的)
inline _variant_t ICrypt::PwdEncode ( VARIANT * aDst, VARIANT * aSrc, VARIANT * aKey ) {
VARIANT _result;
VariantInit(&_result);
HRESULT _hr = raw_PwdEncode(aDst, aSrc, aKey, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _variant_t(_result, false);
}

都是传递的变体的指针! 请大家帮助一下!
simulationz 2007-04-18
  • 打赏
  • 举报
回复
变体型的具体类型,接口参数的一致性
  • 打赏
  • 举报
回复
你都用C++了怎么还用 IDispatch ?
#import "dllname.dll"
然后直接调用接口,这样试试看,应该会调用成功的.
zeuskaaba 2007-04-17
  • 打赏
  • 举报
回复
帮顶!
nicholascheung 2007-04-16
  • 打赏
  • 举报
回复
对 获取对象的com指针对象hr是正确的
执行方法 后 hr也是 成功的?
jixingzhong 2007-04-16
  • 打赏
  • 举报
回复
断点+单步。
注意 参数封装顺序。

问题是 执行的时候 hr 是成功的。
================
hr 从开始到结束,使用次数不少,
一直都是成功的?

COM启动一般没有问题,(检查确认一下)
获得函数名字正确也不会有问题,
可能的问题还是在 Invoke调用处,看看返回的hr提示 ~
freshui 2007-04-16
  • 打赏
  • 举报
回复
buhui
jixingzhong 2007-04-16
  • 打赏
  • 举报
回复
单位有一个很早以前的 com 用于加密的
但是由于 是用的变体类型 不好,导致是用不方便
========================
=_=

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧