刚刚开始学com, 发现很多c的基础知识都不懂.
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
...
...
HRESULT __stcall CA::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<IX*>(this)
}
...
}其中 (void**)&pIX 怎么解释, 我怎么也看不懂. 还有 *ppv 我也看不懂
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
...
...
HRESULT __stcall CA::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<IX*>(this)
}
...
}其中 (void**)&pIX 怎么解释, 我怎么也看不懂. 还有 *ppv 我也看不懂
解决方案 »
- animatewindow怎么使用在自绘子窗口上,高手指点
- 创建向导的问题
- 为什么从int转为unsigned int编译不会报警告
- InsertColumn用法?SetExtendedStyle用法?SetColumnWidth用法?
- 怎么样判断一个文件名是否匹配一个匹配符如:IsMatch("abcdef.txt","ab*.?xt") 返回真。
- 用ShellExecute启动了一个Shell程序 Sample.exe ,怎样等到这个Sample.exe执行结束的时候,才执行下一条语句?
- 高手们快来看看,十万火急,100分全给你
- ClistCtrl自画出现问题?
- 在使用CopyFile拷贝文件之前,要不要需要测试一下这个文件能不能打开,或这个文件正在使用?
- activex控件调用问题
- 开UDP端口时与TCP端口的联系
- 有人知道那个创天是做什么的?它汉化的VC是MS承认的还是纯粹是民间的,怎么用的大都是创天的啊
pI->QueryInterface(IID_IX, (void**)&pIX)
IID_IX是你要查询的接口的GUID,pIX是接口,而&pIX是其地址
在下面的代码中
HRESULT __stcall CA::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<IX*>(this)
}
...
}*ppv = static_cast<IX*>(this)
的*ppv就相当于pIX,上面一行的作用就是为pIX指定值。
调用成功后,就可以通过pIX访问接口的方法。如pIX->...
楼主不应该补习C++,而应该补习C
注意void *pv 和 void **ppv的区别
一个是指针,一个是二级指针,是指向指针的指针
&pv就是指针的地址,相当于ppv,
(void**)&pv,只不过将指针的地址转化为二级指针
void swap(int a,int b){
int tem=a;
a=b;
b=tem;
}///调用int a=10,b=20;
swap(a,b);
cout<<a<<end;cout<<b<<end;
///////////////////
a和b的值不会被交换,交换的只是他们的拷贝。
可以swap(int *a,int *b)来实现a,b值的交换。
同样道理,要想从参数中返回地址,就要一指针的指针的形式获得。这也是
QueryInterface(const IID& iid, void** ppv)
第二个参数是void **的原因。
注意,传void*只能改变指针指向的指,传void**才能改变void*这个指针!呵呵,多多学习:)
与第一个参数类型不对应,也就是说如果第二个参数的指针类型不
为第一个参数的接口指针型类就有可能造成查询错误(因为c++编译器不会报错)。
(void**)这种类型转换本身就是类型不安全的。
就不能用void * ,而是用指向指针的指针。首先应在情感上认同它。至于类型转换是否安全,可以参考bjarne的D&E里面说"即或在窄转换,因为有时真的没有丢失数据,有时的数据截断是用户需要的"。在《程序设计实践》里面也可常见这种做法,它给了这样的表达方式"...转换为适当类型..."。搂主如此认真,我觉得很好,而且我觉得你的水平还要在我之上:)
应该多看书,开卷有益。祝进步!
&pIX 是一个接口指针的地址
(void**)将这个指向指针的指针转换为指向 void 指针的指针
呵呵,是不是还是很晕
如果要改变一个指针的值,那么传送的要么是指针的引用,要么就是指针的地址(指针的指针)
例如:
void getValue(int *pVal)
{
*pVal = 20;
}
int main()
{
int iValue;
getValue(&iValue);
cout<<iValue<<endl;
}
这样你的屏幕上就会打印出20的字样。上例中是要得到INT型的值,就把参数定义成int型指针。
而COM要得到的是接口的指针,所以就需要把接口指针的指针给它就OK了。
如:
HRESULT QueryInterface(IID &iid,Interface **ppInterface)
{
if(....)
*ppInterface = static_cast<...>(this);
}
int main()
{
Interface *pInterface;
pObj->QueryInterface(iid,&pInterface); //pObj是同一对象的另外的一个接口
}
而COM中QueryInterface(IID &iid,Interface **ppInterface)中要查询的接口不可能只一个Interface类型这么简单,多数有实际意义的COM类会支持很多接口。这就需要参数返回的是多种类型,所以COM中就采用了如下的方法
HRESULT QueryInterface(IID &iid,void **ppInterface)
{
if(...)
*ppInterface = static_cast<...>(this);
}int main()
{
Interface *pInterface;
pObj->QueryInterface(iid,(void **)&pInterface);
}
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX);IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
pIX即然要的是接口指针我看Void*就行了。再加一级指针无非就是要
编译器出现类型转型警告。《com本质论》上有说的。