كيف يمكن للمرء أن يعيد ccomsafearray المحلي إلى معلمة إخراج Lpsafearray؟

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

  •  21-09-2019
  •  | 
  •  

سؤال

لدي وظيفة com التي يجب أن تعيد SafeArray عبر a LPSAFEARRAY* المعلمة خارج. تقوم الوظيفة بإنشاء SafeArray باستخدام ATL's CComSafeArray فئة القالب. استخدامي الساذج CComSafeArray<T>::Detach() من أجل نقل الملكية من المتغير المحلي إلى معلمة الإخراج:

void foo(LPSAFEARRAY* psa)
{
    CComSafeArray<VARIANT> ret;
    ret.Add(CComVariant(42));
    *psa = ret.Detach();
}

int main()
{
    CComSafeArray<VARIANT> sa;
    foo(sa.GetSafeArrayPtr());

    std::cout << sa[0].lVal << std::endl;
}

المشكلة هي CComSafeArray::Detach() يؤدي Unlock العملية بحيث عندما يكون المالك الجديد لـ SafeArray (الرئيسي sa في هذه الحالة) يتم تدمير القفل ليس صفرًا و Destroy فشل في فتح SafeArray E_UNEXPECTED (هذا يؤدي إلى تسرب الذاكرة لأن SafeArray لم يتم تعديله).

ما هي الطريقة الصحيحة لنقل الملكية بين ccomsafearrays من خلال حدود طريقة com؟


تعديل: من الإجابة الفردية حتى الآن ، يبدو أن الخطأ موجود إلى جانب العميل (main) وليس من جانب الخادم (foo) ، لكنني أجد صعوبة في تصديق ذلك CComSafeArray لم يكن مصممًا لهذه الحالة التافهة ، يجب أن تكون هناك طريقة أنيقة لإخراج SafeArray من طريقة COM في CComSafeArray.

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

المحلول

المشكلة هي أنك تقوم بتعيين الاستلام CComSafeArrayالمؤشر الداخلي مباشرة. استخدم ال Attach() طريقة لإرفاق موجود SAFEARRAY إلى CComSafeArray:

LPSAFEARRAY ar;
foo(&ar);
CComSafeArray<VARIANT> sa;
sa.Attach(ar);

نصائح أخرى

فقط لتأكيد أن الإجابة المحددة هي الإجابة الصحيحة. لا يمكن لأغلفة Raii العمل عبر حدود com.

تطبيق الطريقة المنشورة غير صحيح ، لا يمكنك افتراض أن المتصل سيوفر SafeArray صالح. فقط [Out] ليست سمة صالحة في الأتمتة ، يجب أن تكون إما [خارج ، Retval] أو [In ، Out]. إذا كان [خارج ، Retval] ، وهو ما يبدو عليه ، فيجب أن تنشئ الطريقة مجموعة جديدة من نقطة الصفر. إذا كان [In ، Out] ، فيجب أن تدمر الطريقة المارة التي تم تمريرها إذا لم تتطابق مع نوع الصفيف المتوقع وإنشاء نموذج جديد.

أعتقد أنه من أين لم يكن نية للسماح بحالة الاستخدام هذه. ربما لم يكن المطور نفسه هو الذي كتب CComVariant & CComPtr :)

أعتقد أن CComSafeArrayالمؤلف يعتبر القيمة الدلالية كهدف رئيسي ؛ قد يكون إرفاق/فصل ميزة "مكافأة" ببساطة.

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