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

Mac下C实现串口DTR/RTS配置正常,Java/JNA移植报错排查

解决JNA调用ioctl配置串口DTR/RTS时的"Inappropriate ioctl for device"问题

我帮你排查到了问题的核心所在——C和Java代码中内存类型不匹配,导致内核无法正确处理TIOCMSET的ioctl请求。

问题根源分析

你的C代码中,lineStatus是int类型(32位),但在Java/JNA代码里却用了LongByReference(对应64位long的指针)。Mac内核的TIOCMSET/TIOCMGET操作期望操作的是32位整数,传递64位指针会让内核无法正确解析数据,直接返回errno=25(不匹配的ioctl设备)。

另外,你的JNA ioctl方法签名中第三个参数的类型也需要对应调整,确保和C端的int*完全匹配。

修正后的Java代码

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
import java.io.PrintStream;

public class Cli {
    /**
     * Java mapping for lib c
     */
    public interface MacCl extends Library {
        String NAME = "c";
        MacCl INSTANCE = Native.load(NAME, MacCl.class);
        
        int open(String pathname, int flags);
        int close(int fd);
        // 调整第三个参数为IntByReference,对应C的int*
        int ioctl(int fd, long request, IntByReference arg);
        String strerror(int errno);
    }

    private static final MacCl C = MacCl.INSTANCE;
    private static PrintStream out = System.err;

    public static void main(String[] argv) {
        // 从C代码输出中复制的常量值
        long TIOCMGET = 0x4004746a;
        long TIOCMSET = 0x8004746d;
        int O_RDWR = 0x2;
        int O_NDELAY = 0x4;
        int O_NOCTTY = 0x20000;

        int value = O_RDWR | O_NDELAY | O_NOCTTY;
        out.printf("value=%x\n", value);

        int portfd = C.open("/dev/tty.usbmodem735ae091", value);
        out.printf("portfd=%d\n", portfd);

        // 替换LongByReference为IntByReference,对应C的int类型
        IntByReference lineStatus = new IntByReference();
        int rc = C.ioctl(portfd, TIOCMGET, lineStatus);
        out.printf("rc=%d, linestatus=%x\n", rc, lineStatus.getValue());

        rc = C.ioctl(portfd, TIOCMSET, lineStatus);
        out.printf("rc=%d errno='%s'\n", rc, C.strerror(Native.getLastError()));

        if (rc == -1) out.print("Failure.");
        else out.print("Success.");

        if (portfd != -1) C.close(portfd);
    }
}

预期输出

修改后运行代码,应该会得到和C代码一致的成功结果:

value=20006
portfd=23
rc=0, linestatus=6
rc=0 errno='Undefined error: 0'
Success.

额外注意事项

  • 确保JNA版本(你用的5.5.0)对Mac平台的指针类型处理正确,IntByReference会准确映射到C的int*。
  • 始终保持JNA中的常量值和C代码输出的完全一致,你已经正确做了这一步,这是避免ioctl错误的基础。

内容的提问来源于stack exchange,提问作者Michael B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:17:46