Tôi có một hàm COM sẽ trả về một SafeArray thông qua tham số LPSAFEARRAY*
. Hàm này tạo SafeArray bằng cách sử dụng lớp mẫu của ATL CComSafeArray
. thực hiện ngây thơ của tôi sử dụng CComSafeArray<T>::Detach()
để chuyển quyền sở hữu từ biến địa phương để các tham số đầu ra:Làm cách nào để trả về một CComSafeArray cục bộ thành tham số đầu ra LPSAFEARRAY?
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;
}
Vấn đề là CComSafeArray::Detach()
thực hiện một hoạt động Unlock
để khi chủ sở hữu mới của SAFEARRAY (chính sa
trong này trường hợp) bị phá hủy khóa không phải là số không và Destroy
không mở khóa SafeArray với E_UNEXPECTED
(điều này dẫn đến rò rỉ bộ nhớ vì SafeArray không được deallocated).
Cách chính xác để chuyển quyền sở hữu giữa cho CComSafeArrays qua ranh giới phương thức COM là gì?
Edit: Từ câu trả lời đơn cho đến nay có vẻ như rằng lỗi là ở phía client (main
) và không phải từ phía máy chủ (foo
), nhưng tôi thấy nó khó để tin rằng CComSafeArray
wasn Không được thiết kế cho trường hợp sử dụng tầm thường này, phải có một cách thanh lịch để có được một SafeArray trong một phương thức COM thành một CComSafeArray
.
Bạn đang sử dụng phiên bản Visual Studio nào? –
Điều này xảy ra cho cả VS8 (2005) và VS9 (2008) – Motti
Dựa trên kinh nghiệm của tôi, tôi tin rằng bất cứ ai thiết kế CComSafeArray chưa bao giờ thực sự sử dụng nó. Bạn có thể sử dụng lớp wrapper của riêng bạn nếu bạn muốn. – Amnon