Строки в этом интерфейсе являются вариантами строк в стиле C (char *), но COM Interop по умолчанию обрабатывает строки как BSTR. У вас есть маршаллер, который пытается прочитать неправильный тип строки, а затем освободить ее с помощью распределителя памяти CoTask, поэтому неудивительно, что вы получили нарушение доступа. Если ваши строки имеют параметры [In], вы можете просто украсить их соответствующим атрибутом MarshalAs, но это не будет работать с параметрами возвращаемого значения. Поэтому вам нужно маршалировать их как IntPtrs, а затем вручную маршалировать и освобождать основную память.
Я бы попробовал следующее:
[Guid("fab51c92-95c3-4468-b317-7de4d7588254"), ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheEntryInfo
{
IntPtr clientID { get; }
IntPtr deviceID { get; }
IntPtr key { get; }
int fetchCount { get; }
uint lastFetched { get; }
uint lastModified { get; }
uint expirationTime { get; }
uint dataSize { get; }
[return: MarshalAs(UnmanagedType.Bool)]
bool isStreamBased();
}
Как упомянул Крис выше, PRUint32 на самом деле являются 32-битными, а не 64-битными целыми числами без знака, поэтому я изменил их. Кроме того, я изменил методы на свойства, так как это лучше отражает значение idl, поскольку все они доступны только для чтения, что на самом деле не влияет на макет.
Строки для clientID и deviceID могут быть прочитаны с помощью Marshal.PtrToStrAnsi следующим образом:
nsIMemory memoryManagerInstance = /*maybe get this from somewhere*/;
nsICacheEntryInfo cacheEntryInstance = /*definitely get this from somewhere*/;
IntPtr pClientID = cacheEntryInstance.clientID;
string clientID = Marshal.PtrToStringAnsi(pClientID);
NS_Free(pClientID);
//or
memoryManagerInstance.free(pClientID);
Используете ли вы NS_Free или интерфейс памяти для освобождения строк, зависит от того, как вы используете всю настройку xpcom. Значение ключа является абстрактной строкой, поэтому ее представление зависит от того, откуда оно взято. Похоже, однако, что его обычно можно рассматривать как указатель на строку ANSI, как и другие.
У меня нет установки, чтобы попробовать что-то подобное для вас, и документация, по меньшей мере, несколько непрозрачна, так что вам, возможно, придется немного подправить это.