对于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;

}


...全文
361 8 打赏 收藏 转发到动态 举报
写回复
用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 用于加密的
但是由于 是用的变体类型 不好,导致是用不方便
========================
=_=
因文件超过20M不能上传,所以拆分为两个文件分次上传 第1章 COM背景知识 1.1 COM的起源 1.1.1 软件业面临的挑战 1.1.2 传统解决方案 1.1.3 面向对象程序设计方法 1.1.4 最终解决方案:组件软件 1.1.5 面向对象的组件模型——COM 1.2 COM的发展历程 1.2.1 COM以前的对象技术:DDE、OLE 1、VBX控件 1.2.2 COM首次亮相:OLE2 1.2.3 Microsoft拥抱Internet:ActiveX 1.2.4 更多的新名词:Windows DNA和COM+ 1.2.5 远程对象:ORBs和DCOM 1.2.6 COM的最新版本:COM+ 1.3 COM技术现状 1.3.1 COM与CORBA 1.3.2 COM与Enterprise Java Beans 1.3.3 Windows之外的COM 小结 第2章 从C++到COM 2.1 C++客户重用C++对象——例程DB 2.1.1 C++对象 2.1.2 客户程序 2.2 将C++对象移进DLL中——例程DB_cppdll 2.2.1 成员函数的引出 2.2.2 内存分配 2.2.3 Unicode/ASCII兼容 2.2.4 例程实现 2.2.4.1 修改接口文件 2.2.4.2 修改对象程序 2.2.4.3 修改客户程序 2.3 C++对象使用抽象基类——例程DB_vtbl 2.3.1 问题:私有数据成员被暴露 2.3.2 解决方案:抽象基类 2.3.2.1 什么是抽象基类(Abstract Base Class) 2.3.2.2 实现秘诀:虚函数(Virtual Functions) 2.3.3 使用抽象基类 2.3.4 例程实现 2.3.4.1 修改接口文件 2.3.4.2 修改对象程序 2.3.4.3 修改客户程序 2.4 改由COM库装载C++对象——例程dbalmostcom 2.4.1 COM库 2.4.2 对象创建的标准入口点 2.4.3 标准对象创建API 2.4.4 标准对象注册 2.4.5 例程实现 2.4.5.1 修改接口文件 2.4.5.2 修改对象程序 2.4.5.3 修改客户程序 2.5 将C++对象变成COM对象 2.5.1 引用计数 2.5.2 多接口 2.5.3 IUnknown接口 2.5.4 标准类厂接口:IClassFactory 2.5.5 对象代码的动态卸载 2.5.6 自动注册 2.5.7 例程实现 2.5.7.1 修改接口文件 2.5.7.2 修改对象程序 2.5.7.3 修改客户程序 2.6 为COM对象添加多接口支持 2.6.1 多接口 2.6.2 DEFINE_GUID 2.6.3 例程实现 2.6.3.1 修改接口文件 2.6.3.2 修改对象程序 2.6.3.3 修改客户程序 小结 第3章 COM基础知识 3.1 对象与接口 3.1.1 COM对象 3.1.2 COM接口 3.1.3 IUnknown接口 3.1.3.1 生存期控制:AddRef和Release 3.1.3.2 接口查询:QueryInterface 3.1.4 全球唯一标识符GUID 3.1.5 COM接口定义 3.1.6 接口描述语言IDL 3.2 COM应用模型 3.2.1 客户/服务器模型 3.2.2 进程内组件 3.2.3 进程外组件 3.2.4 COM库 3.2.5 HRESULT返回值 3.2.6 COM与注册表 3.3 COM组件 3.3.1 实现类厂对象 3.3.2 类厂对象的创建 3.3.3 实现自动注册 3.3.4 实现自动卸载 3.4 COM客户 3.4.1 COM对象创建函数 3.4.1.1 CoGetClassObject 3.4.1.2 CoCreateInstance 3.4.1.3 CoCreateInstanceEx 3.4.2 如何调用进程内组件 3.4.3 COM客户调用进程外组件 3.5 进一步认识COM 3.5.1 可重用机制:包容和聚合 3.5.2 进程透明性 3.5.3 安全性机制 小结 第4章 COM扩展技术 4.1 可连接对象机制 4.1.1 客户、接收器与可连接对象 4.1.1.1 接收器 4.1.1.2 可连接对象 4.1.1.3 客户 4.1.2 实现可连接对象 4.1.3 实现接收器 4.1.4 建立接收器与连接点的连接 4.1.5 获得出接口的类型信息 4.2 结构化存储 4.2.1 什么叫结构化存储和复合文件 4.2.2 存储对象和IStorage接口 4.2.2.1 IStorage接口 4.2.2.2 获得IStorage指针 4.2.2.3 释放STATSTG内存 4.2.2.4 枚举存储对象中的元

64,682

社区成员

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

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