2008-12-26 27 views
14

Khi nào thích hợp để sử dụng CoTaskMemAlloc? Ai đó có thể đưa ra một ví dụ?Việc sử dụng CoTaskMemAlloc?

+0

Tôi đã đăng một số thông tin bên dưới khi bạn có thể cần sử dụng CoTaskMemAlloc, nhưng nó có thể hữu ích cho bạn một số bối cảnh cho câu hỏi của bạn ... – reuben

+0

cố định câu hỏi và tiêu đề của nó một chút. – mmcdole

Trả lời

10

Gosh, tôi đã phải suy nghĩ cho một thời gian cho điều này - Tôi đã thực hiện một số tiền hợp lý của quy mô nhỏ COM lập trình với ATL và hiếm khi đã phải sử dụng nó.

Có một tình huống mà bạn nghĩ đến: Windows Shell extensions. Nếu bạn đang xử lý một tập các đối tượng hệ thống tập tin, bạn có thể phải xử lý PIDLs (con trỏ đến danh sách ID). Đây là những sự trừu tượng hóa các đối tượng hệ thống tập tin kỳ lạ và chúng cần được phân bổ rõ ràng/deallocated bằng cách sử dụng một bộ phân bổ nhận thức COM như CoTaskMemAlloc. Ngoài ra còn có một con trỏ giao diện IMalloc thu được từ SHGetMalloc (không dùng nữa) hoặc CoGetMalloc - nó chỉ là một lớp trừu tượng để sử dụng, để mã của bạn không bị ràng buộc với một bộ cấp phát bộ nhớ cụ thể và có thể sử dụng bất kỳ bộ thích hợp nào.

Điểm của việc sử dụng CoTaskMemAlloc hay IMalloc hơn malloc() là việc phân bổ bộ nhớ/deallocation cần phải được cái gì đó là "COM-aware" để phân bổ và deallocation của nó được thực hiện một cách nhất quán tại thời gian chạy, ngay cả khi việc phân bổ và deallocation được thực hiện bởi mã hoàn toàn không liên quan (ví dụ Windows phân bổ bộ nhớ, chuyển nó vào mã C++ của bạn mà sau này deallocates, hoặc mã C + + của bạn phân bổ, chuyển nó vào mã VB của người khác mà sau này deallocates). Không malloc() cũng không new có khả năng tương tác với heap thời gian chạy của hệ thống, do đó bạn không thể sử dụng chúng để cấp phát bộ nhớ để chuyển sang các đối tượng COM khác hoặc để nhận bộ nhớ từ các đối tượng COM khác và deallocate.

7

This MSDN article so sánh một vài trong số các trình phân bổ khác nhau được tiếp xúc bởi Win32, bao gồm CoTaskMemAlloc. Nó chủ yếu được sử dụng trong lập trình COM - đặc biệt nhất khi việc thực hiện một máy chủ COM cần phải cấp phát bộ nhớ để quay trở lại một máy khách. Nếu bạn không viết một máy chủ COM, thì có thể bạn không cần phải sử dụng nó.

(Tuy nhiên, nếu bạn gọi mã cấp phát bộ nhớ sử dụng CoTaskMemAlloc và trả nó lại cho bạn, bạn sẽ cần phải giải phóng phân bổ trở lại (s) sử dụng CoTaskMemFree.)

+0

Cảm ơn Reuben, yêu cầu của tôi là để cấp phát bộ nhớ từ comserver trong quá trình -> làm một realloc trên cùng một từ phía comclient mà lại là một quá trình khác nhau và sau đó giải phóng nó từ phía comserver ... Tôi hy vọng tôi có thể sử dụng cotaskmemxxx FNS để đạt được cùng - – atVelu

2

CoTaskMemAlloc tương tự như malloc ngoại trừ trường hợp trước đây được sử dụng để cấp phát bộ nhớ được sử dụng trên các ranh giới quy trình.

tức là, nếu chúng tôi có hai quy trình, process1 và process2, giả sử rằng process1 là máy chủ COM và process2 là COM Client sử dụng giao diện được hiển thị bởi process1. Nếu process1 phải gửi một số dữ liệu, thì anh ta có thể cấp phát bộ nhớ bằng CoTaskMemAlloc để cấp phát bộ nhớ và sao chép dữ liệu. Vị trí bộ nhớ đó có thể được truy cập bởi process2.

Thư viện COM tự động thực hiện việc đầm lầy và không sửa đổi.

18

Sử dụng CoTaskMemAlloc khi trả về một char * từ thư viện C++ gốc thành .NET dưới dạng chuỗi.

C#

[DllImport("test.dll", CharSet=CharSet.Ansi)] 
extern static string Foo(); 

C

char* Foo() 
{ 
    std::string response("response"); 
    int len = response.length() + 1; 
    char* buff = (char*) CoTaskMemAlloc(len); 
    strcpy_s(buff, len, response.c_str()); 
    return buff; 
} 

Since .NET uses CoTaskMemFree, bạn phải phân bổ chuỗi như thế này, bạn không thể phân bổ nó trên stack hay đống sử dụng malloc/mới.

+0

Khi được tài nguyên trở bởi 'Foo()' giải thoát? Hoặc nên được thực hiện bằng tay? –

+0

@ChieltenBrinke CLR sẽ thực hiện theo cùng các quy tắc GC cho tài nguyên như đối với tất cả các tài nguyên được quản lý khác. – zz3599

+0

@ zz3599 có nghĩa là gì? CLR cần phải biết tất cả các tham chiếu đến bộ nhớ đó. Nhưng tại thời điểm gọi CoTaskMemAlloc chúng ta vẫn còn trong mã không được quản lý, cho đến chừng nào CLR biết không có tham chiếu đến bộ nhớ đó. Nhưng điều đó có nghĩa là bộ nhớ đó có thể được thu thập ngay sau khi phân bổ nó, đó không phải là trường hợp tôi giả sử, vì nó sẽ làm cho ví dụ này không hợp lệ. Câu hỏi là: làm thế nào nó hoạt động sau đó? –

3

không có thực sự nhiều mà có thể đi sai như các cuộc gọi sau tất cả kết thúc với cùng phân bổ:

CoTaskMemAlloc/SHAlloc -> IMalloc.Alloc -> GlobalAlloc(GMEM_FIXED) 

chỉ nếu bạn sử dụng không cửa sổ (trình biên dịch thư viện) gọi như malloc() mọi thứ sẽ đi sai rồi.

Chính thức ta nên sử dụng CoTaskMemAlloc cho COM gọi (như phân bổ một lĩnh vực FORMATETC.ptd)

Đó CoTaskMemAlloc bằng GlobalAlloc() sẽ ở lại theo cách này 'cho đến vĩnh cửu được nhìn thấy ở các api vào clipboard so com STGMEDIUM. STGMEDIUM sử dụng cấu trúc và phương thức clipboard và trong khi STGMEDIUM là com và do đó CoTaskMemAlloc, apis clipboard quy định GlobalAlloc()

Các vấn đề liên quan