Рассмотрим отрывок из кода, который можно найти здесь :
namespace WinSearchFile
{
public class Parser
{
[DllImport("query.dll", CharSet = CharSet.Unicode)]
private extern static int LoadIFilter (string pwcsPath, ref IUnknown pUnkOuter, ref IFilter ppIUnk);
[ComImport, Guid("00000000-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IUnknown
{
[PreserveSig]
IntPtr QueryInterface( ref Guid riid, out IntPtr pVoid );
[PreserveSig]
IntPtr AddRef();
[PreserveSig]
IntPtr Release();
}
private static IFilter loadIFilter(string filename)
{
IUnknown iunk = null;
IFilter filter = null;
// Try to load the corresponding IFilter
int resultLoad = LoadIFilter( filename, ref iunk, ref filter );
if (resultLoad != (int)IFilterReturnCodes.S_OK)
{
return null;
}
return filter;
}
}
Parser::loadIFilter()
, в этом коде в основном вызывается функция LoadIFilter () .Последний просматривает реестр, находит, какой идентификатор класса соответствует указанному расширению файла, создает экземпляр соответствующего COM-класса (вызывает CoCreateInstance()
) и вызывает из него IPersistFile::Load()
.
Теперь проблема в том, что подписьдля LoadIFilter()
следующее:
HRESULT __stdcall LoadIFilter( PCWSTR pwcsPath, __in IUnknown *pUnkOuter, __out void **ppIUnk );
, поэтому вторым параметром является IUnknown*
объекта агрегирования.Если класс COM для расширения интереса не поддерживает агрегирование, а переданный IUnknown*
не равен нулю CoCreateInstance()
возвращает CLASS_E_NOAGGREGATION
, и так же LoadIFilter()
.
Если я удаляю ref
Ключевое слово из параметра pUnkOuter
в объявлении и на сайте вызова LoadIFilter()
вызывает функцию с нулевым значением IUnknown*
.Если я сохраню ключевое слово ref
, функция будет вызываться с ненулевым IUnknown*
и возвращает CLASS_E_NOAGGREGATION
для классов, которые не поддерживают агрегацию.
Мой вопрос - почему не равен нулю IUnknown*
прошло, когда ключевое слово сохраняется?IUnknown iunk
Локальная переменная инициализируется в null
, так откуда же ненулевое IUnknown*
взято из вызванного неуправляемого кода?