PInvoke - reading the value of a string field - "Attempting to read or write protected memory"

I am having problems accessing some string fields in the COM interface. Calling whole fields does not result in an error. When you try to call clientID(), deviceID()or key()the old error "Attempted to read or write protected memory" appears.

Here is the source code: (code obtained from here )

[scriptable, uuid(fab51c92-95c3-4468-b317-7de4d7588254)]
interface nsICacheEntryInfo : nsISupports
{
    readonly attribute string  clientID;
    readonly attribute string deviceID;
    readonly attribute ACString key;
    readonly attribute long  fetchCount;
    readonly attribute PRUint32  lastFetched;
    readonly attribute PRUint32  lastModified;
    readonly attribute PRUint32  expirationTime;
    readonly attribute unsigned long  dataSize;
    boolean  isStreamBased();
};

Here is the C # code to access the interface:

[Guid("fab51c92-95c3-4468-b317-7de4d7588254"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheEntryInfo
{
    string clientID();
    string deviceID();
    nsACString key();
    int fetchCount();
    Int64 lastFetched();
    Int64 lastModified();
    Int64 expirationTime();
    uint dataSize();
    [return: MarshalAs(UnmanagedType.Bool)]
    bool isStreamBased();
}

Any suggestions as to why just trying to read the field should throw violations at me?

+3
source share
2 answers

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();
}

, PRUint32s 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, ​​ .

, - , , , , .

+3

, statememnt [return: MarshalAs (UnmanagedType.BStr)] ?

0

Source: https://habr.com/ru/post/1720792/


All Articles