如何将XCode(v12.4)的输出流转发至Processing?
将XCode输出转发到Processing的两种可行方案
方法1:读取XCode程序的标准输出(快速实现)
这种方式无需额外工具,直接利用进程间的标准输出管道传输数据,适合简单的一次性数据传输场景。
XCode端代码修改
修改代码,确保输出纯数值(避免多余文本,方便Processing解析):
#include <iostream> #include <unistd.h> // 用于usleep int main(int argc, const char * argv[]) { for (int i = 0; i < 10; i++) { // 仅输出数值+换行,保证Processing能正确解析 std::cout << i << std::endl; // 增加延迟,防止输出过快导致Processing处理不及时 usleep(500000); // 延迟500毫秒 } return 0; }
编译后,找到生成的可执行文件(XCode中右键项目Products下的程序,选择Show in Finder获取绝对路径)。
Processing端代码
通过Process类启动XCode可执行文件,实时读取输出并绘制对象:
Process xcodeProcess; BufferedReader input; String latestValue = ""; void setup() { size(400, 400); try { // 替换为你的XCode可执行文件绝对路径 String execPath = "/Users/你的用户名/Library/Developer/Xcode/DerivedData/项目名/Build/Products/Debug/你的程序名"; xcodeProcess = Runtime.getRuntime().exec(execPath); input = new BufferedReader(new InputStreamReader(xcodeProcess.getInputStream())); } catch (IOException e) { e.printStackTrace(); } } void draw() { background(255); // 读取最新输出值 try { while (input.ready()) { latestValue = input.readLine(); } } catch (IOException e) { e.printStackTrace(); } // 根据数值绘制圆形并显示变量值 if (!latestValue.isEmpty()) { int val = Integer.parseInt(latestValue); ellipse(width/2, height/2, val*20, val*20); fill(0); text("当前值:" + val, 20, 30); } } void exit() { // 退出时销毁进程,避免残留 xcodeProcess.destroy(); super.exit(); }
方法2:虚拟串口通信(适合长期稳定传输)
如果需要高频、持续的数据传输,虚拟串口的方式更稳定可靠。
步骤1:创建虚拟串口
在Mac上可通过第三方工具(如SerialTools)创建一对虚拟串口,例如/dev/tty.usbmodem14101(发送端)和/dev/tty.usbmodem14102(接收端)。
XCode端代码(写入串口)
#include <iostream> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <cstdio> int main(int argc, const char * argv[]) { // 打开虚拟串口 int serialPort = open("/dev/tty.usbmodem14101", O_RDWR | O_NOCTTY | O_NDELAY); if (serialPort == -1) { std::cerr << "无法打开串口" << std::endl; return 1; } // 配置串口参数:波特率9600,8位数据位,无奇偶校验 struct termios options; tcgetattr(serialPort, &options); cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(serialPort, TCSANOW, &options); // 循环发送数值 for (int i = 0; i < 10; i++) { char buffer[10]; sprintf(buffer, "%d\n", i); write(serialPort, buffer, strlen(buffer)); usleep(500000); } // 关闭串口 close(serialPort); return 0; }
Processing端代码(读取串口)
先安装Serial库(菜单Sketch > Import Library > Add Library中搜索安装),再使用以下代码:
import processing.serial.*; Serial serialPort; String latestValue = ""; void setup() { size(400, 400); // 列出所有可用串口,确认虚拟串口路径 String[] ports = Serial.list(); // 替换为你的虚拟串口接收端路径 serialPort = new Serial(this, "/dev/tty.usbmodem14102", 9600); serialPort.bufferUntil('\n'); // 按换行符分割数据 } void draw() { background(255); if (!latestValue.isEmpty()) { int val = Integer.parseInt(latestValue); ellipse(width/2, height/2, val*20, val*20); fill(0); text("当前值:" + val, 20, 30); } } // 串口收到数据时触发的回调 void serialEvent(Serial s) { latestValue = s.readStringUntil('\n').trim(); }
内容的提问来源于stack exchange,提问作者OverFF
相关产品推荐
相关产品推荐

