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 我也看不懂
18 个解决方案
#1
高手都不在线么!
#2
void** 几时指向void*的指针阿
#3
你还是先把C++基础打好了再学COM吧,偶觉得。
#4
你还是先把C++基础打好了再学COM吧,偶觉得。
#5
QueryInterface的作用就是查询指定(第一个参数)的接口,并返回该接口的指针(第二个参数),既然是接口(本身是指针类型),参数中又只能通过指针返回值,那么该参数据的形式就只能是指向指针的指针了,void**的作用就是可以传递各种类型的指针
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->...
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->...
#6
谢谢FBStudio(飞鸟)和LeeZi的指教.
void**的作用就是可以传递各种类型的指针, 那void* 不也是可以传递各种类型的指针么, 请解释一下.
void**的作用就是可以传递各种类型的指针, 那void* 不也是可以传递各种类型的指针么, 请解释一下.
#7
反对 LeeZi(临渊羡鱼,不如退而结网)的意见
楼主不应该补习C++,而应该补习C
注意void *pv 和 void **ppv的区别
一个是指针,一个是二级指针,是指向指针的指针
&pv就是指针的地址,相当于ppv,
(void**)&pv,只不过将指针的地址转化为二级指针
楼主不应该补习C++,而应该补习C
注意void *pv 和 void **ppv的区别
一个是指针,一个是二级指针,是指向指针的指针
&pv就是指针的地址,相当于ppv,
(void**)&pv,只不过将指针的地址转化为二级指针
#8
参数传递是以拷贝形式进行的。如:
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 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 **的原因。
#9
同意: fantong(IT民工 饭桶)
void类型是可以避免编译器进行类型检测,而调用方与被调用方必须在类型上达成一致
void类型是可以避免编译器进行类型检测,而调用方与被调用方必须在类型上达成一致
#10
void**的作用就是可以传递各种类型的指针, 那void* 不也是可以传递各种类型的指针么, 请解释一下.
注意,传void*只能改变指针指向的指,传void**才能改变void*这个指针!呵呵,多多学习:)
注意,传void*只能改变指针指向的指,传void**才能改变void*这个指针!呵呵,多多学习:)
#11
如果你在函数重要改变一个变量的值,那么应该在参数中传变量的指针,如果你要改变的是一个指针的指向呢?自然就应该传这个指针的指针啦这就是(void**)&pIX的作用
#12
大家都说的好啊
#13
实际上QueryInterface的第二个参数是微软为了在视觉上避免用户调用时
与第一个参数类型不对应,也就是说如果第二个参数的指针类型不
为第一个参数的接口指针型类就有可能造成查询错误(因为c++编译器不会报错)。
(void**)这种类型转换本身就是类型不安全的。
与第一个参数类型不对应,也就是说如果第二个参数的指针类型不
为第一个参数的接口指针型类就有可能造成查询错误(因为c++编译器不会报错)。
(void**)这种类型转换本身就是类型不安全的。
#14
void * 它不区分类型用来传递地址,它应该是默认只能指向基本类型int, float, bool。而指针等其他数据类型属于复合类型。因此为了表示指向一个(复合的)指针,
就不能用void * ,而是用指向指针的指针。首先应在情感上认同它。
至于类型转换是否安全,可以参考bjarne的D&E里面说"即或在窄转换,因为有时真的没有丢失数据,有时的数据截断是用户需要的"。在《程序设计实践》里面也可常见这种做法,它给了这样的表达方式"...转换为适当类型..."。
搂主如此认真,我觉得很好,而且我觉得你的水平还要在我之上:)
应该多看书,开卷有益。祝进步!
就不能用void * ,而是用指向指针的指针。首先应在情感上认同它。
至于类型转换是否安全,可以参考bjarne的D&E里面说"即或在窄转换,因为有时真的没有丢失数据,有时的数据截断是用户需要的"。在《程序设计实践》里面也可常见这种做法,它给了这样的表达方式"...转换为适当类型..."。
搂主如此认真,我觉得很好,而且我觉得你的水平还要在我之上:)
应该多看书,开卷有益。祝进步!
#15
呵呵,C语言的基础不扎实啊,回头好好补一补哦
&pIX 是一个接口指针的地址
(void**)将这个指向指针的指针转换为指向 void 指针的指针
呵呵,是不是还是很晕
如果要改变一个指针的值,那么传送的要么是指针的引用,要么就是指针的地址(指针的指针)
&pIX 是一个接口指针的地址
(void**)将这个指向指针的指针转换为指向 void 指针的指针
呵呵,是不是还是很晕
如果要改变一个指针的值,那么传送的要么是指针的引用,要么就是指针的地址(指针的指针)
#16
我想楼上的很多人都说得很好了,但是我没去挨个的看。我觉得这与C++无关,属于C的内容
要想在参数上返回值,你可以看以下谭浩强的C程序设计,其实很简单,只需要把这个数据的指针给它就OK了。
例如:
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);
}
要想在参数上返回值,你可以看以下谭浩强的C程序设计,其实很简单,只需要把这个数据的指针给它就OK了。
例如:
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);
}
#17
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX);
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
pIX即然要的是接口指针我看Void*就行了。再加一级指针无非就是要
编译器出现类型转型警告。《com本质论》上有说的。
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX);
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
pIX即然要的是接口指针我看Void*就行了。再加一级指针无非就是要
编译器出现类型转型警告。《com本质论》上有说的。
#18
up
#1
高手都不在线么!
#2
void** 几时指向void*的指针阿
#3
你还是先把C++基础打好了再学COM吧,偶觉得。
#4
你还是先把C++基础打好了再学COM吧,偶觉得。
#5
QueryInterface的作用就是查询指定(第一个参数)的接口,并返回该接口的指针(第二个参数),既然是接口(本身是指针类型),参数中又只能通过指针返回值,那么该参数据的形式就只能是指向指针的指针了,void**的作用就是可以传递各种类型的指针
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->...
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->...
#6
谢谢FBStudio(飞鸟)和LeeZi的指教.
void**的作用就是可以传递各种类型的指针, 那void* 不也是可以传递各种类型的指针么, 请解释一下.
void**的作用就是可以传递各种类型的指针, 那void* 不也是可以传递各种类型的指针么, 请解释一下.
#7
反对 LeeZi(临渊羡鱼,不如退而结网)的意见
楼主不应该补习C++,而应该补习C
注意void *pv 和 void **ppv的区别
一个是指针,一个是二级指针,是指向指针的指针
&pv就是指针的地址,相当于ppv,
(void**)&pv,只不过将指针的地址转化为二级指针
楼主不应该补习C++,而应该补习C
注意void *pv 和 void **ppv的区别
一个是指针,一个是二级指针,是指向指针的指针
&pv就是指针的地址,相当于ppv,
(void**)&pv,只不过将指针的地址转化为二级指针
#8
参数传递是以拷贝形式进行的。如:
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 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 **的原因。
#9
同意: fantong(IT民工 饭桶)
void类型是可以避免编译器进行类型检测,而调用方与被调用方必须在类型上达成一致
void类型是可以避免编译器进行类型检测,而调用方与被调用方必须在类型上达成一致
#10
void**的作用就是可以传递各种类型的指针, 那void* 不也是可以传递各种类型的指针么, 请解释一下.
注意,传void*只能改变指针指向的指,传void**才能改变void*这个指针!呵呵,多多学习:)
注意,传void*只能改变指针指向的指,传void**才能改变void*这个指针!呵呵,多多学习:)
#11
如果你在函数重要改变一个变量的值,那么应该在参数中传变量的指针,如果你要改变的是一个指针的指向呢?自然就应该传这个指针的指针啦这就是(void**)&pIX的作用
#12
大家都说的好啊
#13
实际上QueryInterface的第二个参数是微软为了在视觉上避免用户调用时
与第一个参数类型不对应,也就是说如果第二个参数的指针类型不
为第一个参数的接口指针型类就有可能造成查询错误(因为c++编译器不会报错)。
(void**)这种类型转换本身就是类型不安全的。
与第一个参数类型不对应,也就是说如果第二个参数的指针类型不
为第一个参数的接口指针型类就有可能造成查询错误(因为c++编译器不会报错)。
(void**)这种类型转换本身就是类型不安全的。
#14
void * 它不区分类型用来传递地址,它应该是默认只能指向基本类型int, float, bool。而指针等其他数据类型属于复合类型。因此为了表示指向一个(复合的)指针,
就不能用void * ,而是用指向指针的指针。首先应在情感上认同它。
至于类型转换是否安全,可以参考bjarne的D&E里面说"即或在窄转换,因为有时真的没有丢失数据,有时的数据截断是用户需要的"。在《程序设计实践》里面也可常见这种做法,它给了这样的表达方式"...转换为适当类型..."。
搂主如此认真,我觉得很好,而且我觉得你的水平还要在我之上:)
应该多看书,开卷有益。祝进步!
就不能用void * ,而是用指向指针的指针。首先应在情感上认同它。
至于类型转换是否安全,可以参考bjarne的D&E里面说"即或在窄转换,因为有时真的没有丢失数据,有时的数据截断是用户需要的"。在《程序设计实践》里面也可常见这种做法,它给了这样的表达方式"...转换为适当类型..."。
搂主如此认真,我觉得很好,而且我觉得你的水平还要在我之上:)
应该多看书,开卷有益。祝进步!
#15
呵呵,C语言的基础不扎实啊,回头好好补一补哦
&pIX 是一个接口指针的地址
(void**)将这个指向指针的指针转换为指向 void 指针的指针
呵呵,是不是还是很晕
如果要改变一个指针的值,那么传送的要么是指针的引用,要么就是指针的地址(指针的指针)
&pIX 是一个接口指针的地址
(void**)将这个指向指针的指针转换为指向 void 指针的指针
呵呵,是不是还是很晕
如果要改变一个指针的值,那么传送的要么是指针的引用,要么就是指针的地址(指针的指针)
#16
我想楼上的很多人都说得很好了,但是我没去挨个的看。我觉得这与C++无关,属于C的内容
要想在参数上返回值,你可以看以下谭浩强的C程序设计,其实很简单,只需要把这个数据的指针给它就OK了。
例如:
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);
}
要想在参数上返回值,你可以看以下谭浩强的C程序设计,其实很简单,只需要把这个数据的指针给它就OK了。
例如:
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);
}
#17
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX);
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
pIX即然要的是接口指针我看Void*就行了。再加一级指针无非就是要
编译器出现类型转型警告。《com本质论》上有说的。
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX);
IX* pIX = NULL;
HRESULT hr = pI->QueryInterface(IID_IX, (void**)&pIX)
pIX即然要的是接口指针我看Void*就行了。再加一级指针无非就是要
编译器出现类型转型警告。《com本质论》上有说的。
#18
up