求达人解惑:
在定义devctl使用的cmd code时,需要给出的一个参数是这个cmd code的传输buffer的长度, 不确定的地方就是这个长度:他规定的是这个cmd code的传输buffer的最小长度,还是必须是精确的一个传输长度? 如果是后者,那么如果一个cmd,他的buffer是变长的,是不是就必须手工把他分割为定长来传输?
先谢过了!
求达人解惑:
在定义devctl使用的cmd code时,需要给出的一个参数是这个cmd code的传输buffer的长度, 不确定的地方就是这个长度:他规定的是这个cmd code的传输buffer的最小长度,还是必须是精确的一个传输长度? 如果是后者,那么如果一个cmd,他的buffer是变长的,是不是就必须手工把他分割为定长来传输?
先谢过了!
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来进行了。
谢谢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
非常非常感谢!
这下清楚了。
再一次的感谢xtang!!!