新手求助:关于devctl 的问题。

求达人解惑:
在定义devctl使用的cmd code时,需要给出的一个参数是这个cmd code的传输buffer的长度, 不确定的地方就是这个长度:他规定的是这个cmd code的传输buffer的最小长度,还是必须是精确的一个传输长度? 如果是后者,那么如果一个cmd,他的buffer是变长的,是不是就必须手工把他分割为定长来传输?

先谢过了! :laughing:

int devctl( int filedes,
            int dcmd,
            void * dev_data_ptr,
            size_t n_bytes,
            int * dev_info_ptr );

你说的是n_bytes吗?这个必须是精确长度。

即使数据区是变长,在调用devctl()的时候如果能知道准确长度就没有问题了。

如果在调用devctl()时,确实无法知道传递数据长度的,那只能在控制区里加入 start,continue, end这样的bits来进行了。

:laughing:

谢谢xtang。

我说的是__DIOT (xxx, xxx, xxx_type) 中的最后那个参数,那个type会被用来计算一个长度,编码到cmd code的高16位。

在真正调用devctl时,确切的长度是知道的,只不过在定义cmd code时,还不能确定,所以,在windows下(抱歉,以这个为例)那可type一般会定义为:
struct xxx{
byte data[1];
}

不知道这样在qnx中是否可行。主要就在于qnx的cmd code中包含有传输长度的编码域。

那个长度,是个历史遗留问题。以前,没有devctl时,UNIX的通用函数是ioctl(),那时,要传递变长,只能先传指针+长度,然后由对方来读取。POSIX后来扩展了ioctl(),变成了现在用的devctl(),可以在命令行传入数据长度了,dcmd里的长度就变得不太重要了。

以你的例子,你可以定义:

struct xxx {
    size_t  datalen;
    byte    data[0];
};

dcmd里直接用 sizeof(struct xxx); 如果你实在不想要这个datalen,也可以直接在dcmd里置 0,然后在devctl()里传你的数据,就行了。

需要指出的是,千万不要用devctl()来传一指针+长度,因为接收方(服务器端)是没法回读你的数据的。如果你有不止一块变长数据,可以设iov_t,有devctlv()函数可用。

还有就是在服务器端,所有传进来的数据,都会连在一起,服务器收到的是这样的连在一起的块。

struct _io_devctl msg;
struct xxx;
data + datalen from devctl() call

:smiley:
非常非常感谢!

这下清楚了。

再一次的感谢xtang!!!