2010-03-21 43 views

Trả lời

7

Tôi khá chắc chắn rằng có một cách, nhưng nó có lẽ là một ý tưởng tồi. Làm thế nào bạn sẽ đảm bảo rằng thời gian chạy đã không được gọi là một số chức năng CRT trong quá trình xử lý nội bộ của nó đã ảnh hưởng đến errno?

Vì lý do tương tự, bạn cũng không nên gọi trực tiếp số GetLastError. Các DllImportAttribute cung cấp một tài sản SetLastError để thời gian chạy biết ngay lập tức nắm bắt được lỗi cuối cùng và lưu trữ nó ở một nơi mà mã được quản lý có thể đọc bằng cách sử dụng Marshal.GetLastWin32Error.

Tôi nghĩ rằng điều mạnh mẽ nhất bạn có thể làm trong trường hợp này là tạo một DLL C thực hiện cả công việc C thực tế và chụp errno. (Lưu ý rằng chỉ cần viết một wrapper xung quanh chụp errno vẫn sẽ có những mối quan tâm được đề cập ở trên.)

+0

Vâng, tôi đồng ý với điều này. Nó có lẽ sẽ là tốt hơn để thiết lập một wrapper C một chức năng mục tiêu mà lần lượt sẽ trả về giá trị của errno từ đó. – supercheetah

2

Có, có thể - GetLastError thực hiện chính xác điều đó. Tuy nhiên, như binarycoder đã chỉ ra, bạn không nên thực hiện điều này trực tiếp - thay vào đó, hãy đặt SetLastError trên DllImport để tự động thực hiện và lưu trữ bộ nhớ cache (và để tránh các vấn đề đa luồng hoặc các hàm gọi thời gian sửa đổi giá trị errno) - P/Chức năng được viện dẫn, kiểm tra trạng thái trả về của nó và nếu nó hiển thị một điều kiện lỗi - hãy ném Win32Exception, tự động đọc giá trị của lỗi cuối cùng. Có, ngay cả trên Mono trên Linux.

2

Giải pháp là sử dụng SetLastError trên DllImport. Điều này sẽ làm cho thời gian chạy lưu lỗi cuối cùng để có thể truy cập từ Marshal.GetLastWin32Error.

Có hai vấn đề với gọi GetLastError trực tiếp:

  • Thời gian chạy có thể làm đôi sau khi PInvoke trả trước khi bạn có thể nhận được lỗi cuối cùng
  • Nhiều chủ đề .NET có thể cư trú trên cùng một mẹ đẻ chủ đề. Điều này có thể dẫn đến 2 chủ đề .NET thực hiện PInvokes, các thư viện nguyên gốc không biết gì tốt hơn, sau đó sẽ ghi đè lên lỗi cuối cùng. Vì vậy, thread A in .NET nhận được lỗi cuối cùng của thread B (có khả năng).
+0

Bạn có thể hiển thị ví dụ về cú pháp để sử dụng 'SetLastError' trên' DllImport' không? –

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