در این مقاله، به بررسی چگونگی حفظ دسترسی به دادههای موجود در یک SAFEARRAY پس از بازگشت یک متد میپردازیم. مشکل اصلی که مشتری با آن مواجه بود، از بین رفتن دادهها در SAFEARRAY بود، حتی پس از فراخوانی SafeArrayAddRef. این موضوع به دلیل ماهیت SAFEARRAY به عنوان یک شیء با مالکیت منحصر به فرد رخ میدهد.
SAFEARRAY یک شیء با مالکیت منحصر به فرد است. هنگامی که مالک، SafeArrayDestroy را فراخوانی میکند، آرایه از بین میرود. با استفاده از SafeArrayAddRef میتوان طول عمر حافظه را افزایش داد، اما دادههای خود از بین رفتهاند. هدف از افزایش طول عمر حافظه، اجازه دادن به استفاده از آرایه نیست، بلکه جلوگیری از دسترسی به حافظه آزاد شده در صورتی است که آرایه از زیر دست شما نابود شود.
برای جلوگیری از فراخوانی SafeArrayDestroy توسط مالک فعلی، باید مالک فعلی را متقاعد کرد که مالکیت را به شما واگذار کند. در این صورت، شما مسئول فراخوانی SafeArrayDestroy خواهید بود و میتوانید این کار را زمانی که با آرایه تمام کردید انجام دهید. یک راه حل پیشنهادی استفاده از یک VARIANT به عنوان پارامتر ورودی/خروجی است. در ابتدا، VARIANT شامل یک SAFEARRAY است. سپس میتوانید parray را از VARIANT جدا کرده و نوع VARIANT را به VT_EMPTY بازنشانی کنید.
این روش، اگرچه ایدهآل نیست، اما راه حلی قابل قبول است. این رویکرد به وضوح نشان میدهد که متد ممکن است تصمیم به تغییر آرایه به چیزی دیگر بگیرد، بنابراین اگر فراخواننده هنوز به دادههای آرایه نیاز دارد، باید یک کپی از دادهها را ارسال کند تا بتواند از دادههای اصلی استفاده کند. در این حالت، کپیبرداری به سادگی به فراخواننده منتقل میشود. اما در صورتی که فراخواننده قصد نابودی آرایه را داشته باشد، میتواند آرایه را در VARIANT قرار دهد و اگر متد آرایه را در طول فراخوانی متد نابود کند، مشکلی وجود نخواهد داشت، زیرا آرایه در حال نابودی بوده است.
مشاهده مطلب اصلی