【问题标题】:xcode create command line window like windows doesxcode 像 windows 一样创建命令行窗口
【发布时间】:2023-04-11 12:49:01
【问题描述】:

我有一个 windows 应用程序,我用 GLFW 将它移植到 mac。在 Win32 中,我通过::AllocConsole(); 创建了一个 cmd 窗口。我用它来调试我的脚本。但是在 mac 中,似乎没有办法从运行进度中创建一个 cmd 窗口。 lldb 适用于 C++ 部分,但对我的 python 脚本部分没有帮助。我试图创建一个 GLFW 窗口来伪造它,但 GLFW 只能运行一个实例,如果我挂断我的应用程序,所有窗口都会暂停。所以,我正在寻找一种在子线程中从我的应用程序创建窗口的方法,它可以用作调试工具来与我的应用程序进行交互。

【问题讨论】:

    标签: python c++ xcode windows macos


    【解决方案1】:

    感谢您提出的精彩问题。我花了一点时间才想出一些适用于任何类 Unix 系统的东西。

    这是一个起点。我会留给其他人完善它。

    要点:

    • 将进程分叉到主程序和子程序中。

    • 主程序将 unix 域套接字 iostream 连接到其选择的 unix 套接字名称。

    • 子进程生成一个 xterm 进程,该进程使用特殊的命令行选项运行相同的程序,并为其提供 unix 域套接字的名称。

    • 在 xterm 下运行的程序的衍生版本侦听 unix 套接字并将其接收到的所有数据重复到标准输出(在 xterm 窗口中)。

    • 原始程序现在可以将数据记录到 unix 域 io_stream 以发出调试数据。

    这个程序应该也可以在 cygwin 下的 windows 下运行。

    #include <iostream>
    #include <memory>
    #include <chrono>
    #include <system_error>
    #include <thread>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <boost/asio.hpp>
    
    
    using namespace std;
    
    namespace asio = boost::asio;
    
    asio::io_service io_service;
    asio::local::stream_protocol::iostream log_stream;
    
    int run_program(int argc, char** argv)
    {
        for (int i = 0 ; i < 100 ; ++i) {
            cout << "logging first" << endl;
            log_stream << i << " hello" << endl;
            cout << "logged" << endl;
            this_thread::sleep_for(chrono::milliseconds(400));
        }
        return 0;
    }
    
    
    auto main(int argc, char** argv) -> int
    {
        if (argc == 3
            && strcmp(argv[1], "--repeat") == 0)
        {
            auto socket_name = string(argv[2]);
    
            cout << "listening on " << socket_name << endl;
    
            ::unlink(socket_name.c_str()); // Remove previous binding.
            asio::local::stream_protocol::endpoint ep(socket_name);
            asio::local::stream_protocol::acceptor acceptor(io_service, ep);
            asio::local::stream_protocol::socket socket(io_service);
            acceptor.accept(socket);
            cout << "accepted" << endl;
            while (1) {
                char buf[100];
                auto bytes_read = socket.read_some(asio::buffer(buf));
                if (bytes_read > 0) {
                    cout.write(buf, bytes_read);
                    cout.flush();
                }
                else {
                    socket.close();
                    exit(0);
                }
            }
        }
        else {
            const auto socket_name = "/tmp/foo"s;
    
            cout << "forking" << endl;
            auto client_pid = fork();
            if (client_pid == 0) {
                cout << "in client" << endl;
                ostringstream ss;
                ss << "xterm -e " << argv[0] << " --repeat " << socket_name;
                auto s = ss.str();
                auto err = system(s.c_str());
                if (err) {
                    throw system_error(errno, system_category(), "logger child execution");
                }
            }
            else if (client_pid == -1) {
                throw system_error(errno, system_category(), "forking");
            }
            else {
                cout << "pause to allow xterm client to start" << endl;
                this_thread::sleep_for(chrono::seconds(2));
                cout << "making endpoint " << socket_name << endl;
                asio::local::stream_protocol::endpoint endpoint(socket_name);
                cout << "connecting to " << endpoint << endl;
    
                log_stream.connect(endpoint);
                cout << "connected" << endl;
    
                auto ret = run_program(argc, argv);
    
                log_stream.close();
                exit(ret);
            }
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 2012-11-03
      相关资源
      最近更新 更多