Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“的奇怪后果”;参考「;C#to COM互操作中的关键字_C#_Windows_Com_Interop_Com Interop - Fatal编程技术网

“的奇怪后果”;参考「;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的站点上,将使用null
IUnknown*
调用该函数。如果保留
ref
关键字,则函数将使用非null
IUnknown*
调用,并为不支持聚合的类返回
CLASS\u E\u NOAGGREGATION


我的问题是-保留关键字时为什么传递非null
IUnknown*
IUnknown iunk
局部变量被初始化为
null
那么非null
IUnknown*
在被调用的非托管代码中从何而来?

当您使用
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++中对应于InOxt**/Cuth>的地址被被调用的人解释为<代码> iNoX**/Cube >,这样后者会冒着完全未定义的行为的危险吗?听起来很可怕,但相当。合理的。谢谢。你的意思是它们有效地传递了本地变量的地址,C++中对应于 iNox**>代码>的地址被被调用的人解释为代码> iNoX**/Cube >,这样后者就被完全定义为未定义的行为?听起来很可怕但还是很合理的。非常感谢。