2010-01-09 39 views
8

Tôi có lệnh chuỗi mà tôi muốn thực thi không đồng bộ trong khi ghi vào đầu vào và đọc đầu ra của nó. Nghe có vẻ dễ dàng, đúng vậy, ma quỷ ở trong nền tảng chéo. Tôi đang nhắm mục tiêu cả MSVC/Win32 và gcc/Linux và rõ ràng là muốn viết số lượng mã nền tảng cụ thể tối thiểu. Google-fu của tôi đã thất bại với tôi, tôi nhận được quá nhiều tiếng ồn cho các truy vấn của tôi, vì vậy tôi bắt đầu với những gì tôi biết.Chuyển hướng đa nền tảng đầu vào và đầu ra tiêu chuẩn của quá trình sinh ra trong C/C++ (chỉnh sửa bằng giải pháp)

popen - đẹp và dễ dàng, trả về TẬP_TIN * dễ dàng tiêu thụ ở mọi nơi. Nhưng đây là những gì MSDN have to say about _popen:

Nếu được sử dụng trong một chương trình Windows, _popen hàm trả về một con trỏ tập tin không hợp lệ mà làm cho chương trình để ngừng đáp ứng vô thời hạn. _popen hoạt động bình thường trong ứng dụng bảng điều khiển. Để tạo ứng dụng Windows chuyển hướng đầu vào và đầu ra , hãy xem Tạo quy trình con với đầu vào và đầu ra được chuyển hướng trong SDK nền tảng.

và do đó popen nằm ngoài câu hỏi (chỉnh sửa: vì tôi muốn mã của tôi hoạt động trong ứng dụng GUI). Cách Windows để làm điều đó là theo ý kiến ​​của tôi khá xấu xí và tiết tú. Tôi có thể sống với mã đẻ trứng cụ thể nhưng tôi muốn ít nhất mã I/O giống nhau. Tuy nhiên, ở đây, tôi đã nhấn vào một bức tường giữa các trình mô tả tệp WinAPI HANDLE s và C FILE*int. Có cách nào để "chuyển đổi" một số HANDLE thành FILE* hoặc int fd hoặc ngược lại không? (Google đã thất bại một lần nữa cho tôi, tất cả từ khóa tôi đã thử đều bị lạm dụng)

Có cách nào tốt hơn để làm toàn bộ điều với mã nền tảng cụ thể không?

Thư viện bên ngoài không nằm ngoài câu hỏi, tuy nhiên việc bảo trì phụ thuộc là một nỗi đau, đặc biệt là trên nhiều nền tảng, vì vậy tôi muốn giảm phụ thuộc. Tôi cũng không tìm được thư viện như vậy.


Chỉ để lưu nội dung, những gì hiệu quả với tôi cuối cùng. Trên Windows/MSVC, CreatePipe() + CreateProcess() như được nêu here, sử dụng _open_osfhandle(), tiếp theo là _fdopen() để nhận FILE* cho quá trình nhập và xuất. Trên Linux/GCC, không có gì mới ở đây, tạo ra pipe() s; fork() rồi dup2() các đường ống; exec(); fdopen() trên các mô tả tệp có liên quan. Bằng cách đó, chỉ có quy trình tạo mã phụ thuộc nền tảng (điều này là ok, như trên Windows tôi muốn kiểm soát các tham số STARTUPINFO bổ sung), đầu vào ghi và đầu ra đọc được thực hiện thông qua các tiêu chuẩn FILE* và các chức năng liên quan.

+0

Bạn không nói nếu bạn đang viết một GUI hoặc một ứng dụng giao diện điều khiển. Nếu sau này, popen() không hoạt động trên Windows. –

Trả lời

6

Tặng libexecstream một vòng xoáy. Đó là nền tảng chéo, và cho phép bạn bẫy các luồng đầu vào, đầu ra và lỗi của một tiến trình không đồng bộ như các luồng kiểu C++.

Tôi đã sử dụng nó trên Linux, Darwin và Windows và có vẻ như nó hoạt động. Nó cũng khá nhẹ nên tích hợp vào các dự án có ít đau đớn và có giấy phép BSD khá mở. Tôi không nghĩ rằng có bất kỳ cách nào xung quanh bằng cách sử dụng một thư viện (khác hơn là viết các biến thể của riêng bạn cho mỗi nền tảng).

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