PInvoke - قراءة قيمة من حقل السلسلة - "حاول قراءة أو كتابة الذاكرة المحمية"

StackOverflow https://stackoverflow.com/questions/1607380

  •  05-07-2019
  •  | 
  •  

سؤال

أواجه مشكلة في الدخول إلى بعض حقول السلسلة في واجهة COM.استدعاء عدد من المجالات لا ينتج خطأ.عند محاولة الاتصال clientID(), deviceID() أو key(), أنا الحصول على القديم "حاول قراءة أو كتابة الذاكرة المحمية" خطأ.

هنا هو مصدر واجهة البرمجية: (رمز مصدرها هنا)

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

هنا هو C# كود للوصول إلى واجهة:

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

أي اقتراحات لماذا ببساطة محاولة قراءة حقل يجب رمي الوصول الانتهاكات ؟

هل كانت مفيدة؟

المحلول

السلاسل في هذه الواجهة هي المتغيرات على C أسلوب السلاسل (char*s) ولكن COM إمكانية التشغيل المتداخل بشكل افتراضي يعامل سلاسل BSTRs.لديك marshaller محاولة قراءة هذا النوع الخاطئ من سلسلة ثم مجانية مع CoTask مخصص الذاكرة ، لذلك فإنه ليس من المستغرب تحصل إلى انتهاك حقوق الوصول.إذا كانت السلاسل [في] المعلمات هل يمكن أن مجرد تزين لهم مع المناسبة 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 يمكن قراءتها باستخدام المشير.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 مثل الآخرين.

لا يكون الإعداد محاولة أي من هذه لك والوثائق ، على أقل تقدير ، مبهمة إلى حد ما لذلك قد تحتاج إلى القيام به القليل من التغيير والتبديل على هذا.

نصائح أخرى

ما إذا كان تطبيق [عودة:MarshalAs(UnmanagedType.BStr)] statememnt إلى clientID و deviceID ?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top