2010-01-19 35 views
5

Có nên sử dụng các hàm C API để phân bổ đầu ra của chúng hay để người dùng chỉ định bộ đệm đầu ra? Ví dụ:Thiết kế API - phân bổ đầu ra?

BOOL GetString(
    PWSTR *String 
    ); 
... 
PWSTR string; 
GetString(&string); 
Free(string); 

vs

BOOL GetString(
    PWSTR Buffer, 
    ULONG BufferSize, 
    PULONG RequiredBufferSize 
    ); 
... 
// A lot more code than in the first case 

Cụ thể hơn, tôi tự hỏi tại sao các API Win32 chủ yếu sử dụng trường hợp thứ hai (ví dụ GetWindowText, LookupAccountSid). Nếu một hàm API biết đầu ra lớn như thế nào, tại sao người dùng cố gắng đoán kích thước đầu ra? Tôi không thể tìm thấy bất kỳ thông tin nào về lý do trường hợp thứ hai sẽ được sử dụng.

Ngoài ra: ví dụ LookupAccountSid đặc biệt xấu. Bên trong nó sử dụng API LSA, phân bổ đầu ra cho người gọi. Sau đó, LookupAccountSid được người dùng phân bổ một bộ đệm (và đoán kích thước bộ đệm chính xác) khi nó chỉ có thể trả về kết quả từ LSA! Tại sao?

+0

Điều đó tùy thuộc. Cả hai thành ngữ đều được sử dụng. Cả hai đều có điểm cộng và nhược điểm. –

+0

Ưu điểm của trường hợp thứ hai sau đó, ngoài việc có thể sử dụng bộ đệm dựa trên stack? – wj32

+0

Nó cho phép người gọi sử dụng sự lựa chọn của họ về phân bổ. Nếu bạn cấp phát bộ nhớ và để nó cho người gọi miễn phí, người gọi cần sử dụng deallocater tương ứng - có thể không phải là sở thích của họ. Việc lấp đầy bộ đệm do người gọi cung cấp cho phép họ chọn một người phân bổ thích hợp cho mục đích của họ, thay vì dựa vào API mà họ đã chọn. –

Trả lời

5

API Win32 không phân bổ trước bộ đệm vì nó muốn cung cấp mã gọi để lựa chọn cách cung cấp bộ đệm. Nó cho phép họ cung cấp stack và một loạt các bộ đệm dựa trên heap. Có một số nơi mà kích thước tối đa của bộ đệm được biết trước thời hạn và các nhà phát triển muốn sự đơn giản của việc sử dụng một bộ đệm dựa trên stack.

Hệ thống tệp là ví dụ tốt nhất vì đường dẫn sẽ không vượt quá MAX_PATH. Vì vậy, thay vì phân bổ + miễn phí. Nhà phát triển chỉ cần khai báo bộ đệm dựa trên stack.

Lợi thế để có bộ nhớ cấp phát API C là nó đơn giản hóa mẫu gọi. Nhược điểm của mô hình Win32 là hầu hết các lần bạn kết thúc gọi API hai lần. Lần đầu tiên để xác định kích thước của bộ đệm, sau đó là lần thứ hai với bộ đệm có kích thước phù hợp. Với bộ đệm được cấp phát API chỉ cần một cuộc gọi.

Tuy nhiên, nhược điểm là bạn lấy đi sự lựa chọn phân bổ từ người gọi. Ngoài ra, bạn phải truyền đạt sự lựa chọn của mình để chúng có thể giải phóng API một cách chính xác (ví dụ: các cửa sổ có thể phân bổ từ nhiều nơi khác nhau).

+3

Tôi muốn lưu ý rằng nó rất đơn giản để kết nối hai cuộc gọi cộng với phân bổ trong chức năng của riêng bạn, đơn giản hóa mẫu gọi là một mối quan tâm rất nhỏ. Nếu bạn chỉ cung cấp một phiên bản của API, nó phải là một phiên bản linh hoạt hơn. –

1

Cách tiếp cận thứ hai có một số lợi thế như

  • Nó cho phép người gọi quản lý cuộc đời của cấp phát bộ nhớ
  • Nó cho phép người gọi để tái sử dụng bộ nhớ được phân bổ cho các cuộc gọi khác nhau mà theo đó cùng mẫu
  • Nó cho phép người gọi quyết định bộ đệm nào để cung cấp ví dụ ngăn xếp hoặc đống.
Các vấn đề liên quan