You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:21:01