【问题标题】: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;
}