“的奇怪后果”;参考「;C#to COM互操作中的关键字
考虑一段代码摘录,可以找到:“的奇怪后果”;参考「;C#to COM互操作中的关键字,c#,windows,com,interop,com-interop,C#,Windows,Com,Interop,Com Interop,考虑一段代码摘录,可以找到: Parser::loadIFilter()在该代码中基本上调用函数。后者查找注册表,找到与指定文件扩展名对应的类id,实例化相应的COM类(调用CoCreateInstance())并从中调用IPersistFile::Load()) 现在的问题是LoadIFilter()的签名如下: HRESULT __stdcall LoadIFilter( PCWSTR pwcsPath, __in IUnknown *pUnkOuter, __out void **ppIU
Parser::loadIFilter()
在该代码中基本上调用函数。后者查找注册表,找到与指定文件扩展名对应的类id,实例化相应的COM类(调用CoCreateInstance()
)并从中调用IPersistFile::Load()
)
现在的问题是LoadIFilter()
的签名如下:
HRESULT __stdcall LoadIFilter( PCWSTR pwcsPath, __in IUnknown *pUnkOuter, __out void **ppIUnk );
因此,第二个参数是聚合对象的IUnknown*
。如果感兴趣的扩展的COM类不支持聚合,并且传递的IUnknown*
不为空CoCreateInstance()
返回class\u E\u NOAGGREGATION
,LoadIFilter()
如果我从声明中的pUnkOuter
参数中删除ref
关键字,并且在LoadIFilter()
call的站点上,将使用nullIUnknown*
调用该函数。如果保留ref
关键字,则函数将使用非nullIUnknown*
调用,并为不支持聚合的类返回CLASS\u E\u NOAGGREGATION
我的问题是-保留关键字时为什么传递非null
IUnknown*
IUnknown iunk
局部变量被初始化为null
那么非nullIUnknown*
在被调用的非托管代码中从何而来?当您使用ref
时,您实际上并没有发送null
,而是发送一个指向null
存储位置的引用,但是当您在没有ref
的情况下发送时,您发送的是实际值,即null
因此:
对于ref,它是对空指针的引用
没有它,它只是一个空指针
编辑:如果我正确理解了你的问题,我不是百分之百确定的…当你使用
ref
时,你实际上并没有发送null
,而是发送了一个指向null
存储位置的引用,但是当你在没有ref
的情况下发送时,你发送的是实际值,这是null
因此:
对于ref,它是对空指针的引用
没有它,它只是一个空指针
编辑:如果我正确理解了您的问题,我不是100%确定的…非空位来自方法内部-它将对象实例化到您提供的引用上。在引用类型上使用ref关键字将调用方引用传递给对象,而不是创建对对象的另一个引用(通常通过引用传递时会发生这种情况)。试试这个:
static void Main()
{
object foo = null;
SetMyObject(ref foo);
bool test = foo == null;
}
public static void SetMyObject(ref object foo)
{
foo = new object();
}
变量测试将为false。非空位来自方法内部-它将对象实例化到您提供的引用上。在引用类型上使用ref关键字将调用方引用传递给对象,而不是创建对对象的另一个引用(通常通过引用传递时会发生这种情况)。试试这个:
static void Main()
{
object foo = null;
SetMyObject(ref foo);
bool test = foo == null;
}
public static void SetMyObject(ref object foo)
{
foo = new object();
}
变量测试将为false。使用ref完全错误,您的IUnknown已作为指针传递,因为它是一个接口。传递ref相当于IUnknown**使用ref是完全错误的,您的IUnknown已经作为指针传递,因为它是一个接口。通过ReF将等同于InOxL**/P>,那么,你的意思是它们有效地传递了局部变量的地址,C++中对应于