XChangeProperty使用long为32位

时间:2016-01-14 21:52:14

标签: c x11 sparc

传递给XChangeProperty()的pid变量不长。 libX11代码将变量视为long和64位sparc 这必须在8字节边界上对齐。 因为它是一个int,它在4字节边界上对齐,导致a 总线错误。

pid_t pid = getpid();
XChangeProperty( display, wm_window, net_wm_pid, cardinal, 32,
                 PropModeReplace,
                 (const unsigned char*) &pid, 1 );

它只需要演员'长'或检查最大值?

来自XGetWindowProperty(3) manual page

  

格式
              指定是否应将数据视为列表               8位,16位或32位数量。可能的值是               8,               16,和32.这个信息允许X服务器               根据需要直接执行字节交换操作。如果               格式是16位或32位,你必须明确地投射你的               数据指向调用中的(unsigned char *)               XChange-               属性。

pid_t pid = getpid ();
if (pid <= 0xFFFFFFFFU) {
    unsigned long xpid = pid;

    XChangeProperty( display, wm_window, net_wm_pid, cardinal, 32,
                     PropModeReplace,
                     (const unsigned char*) &xpid, 1 );
}

1 个答案:

答案 0 :(得分:4)

您必须为您正在设置的32位属性传递一个long到XChangeProperty。

所以你需要做

unsigned long xpid = pid;

如果pid_t是32位或更少,则无需检查它是否为&lt; = 0xFFFFFFFFU,它将始终为真。

如果您希望将代码移植到具有pid_t值&gt;的系统。 32位 - (虽然我不知道任何系统有)然后你需要检查,因为_NET_WM_PID属性被定义为32位。

这里的根本问题是libX11会将该属性取消引用为long,但只从中提取32位,所以我可以告诉_NET_WM_PID如果pid_t值不能在系统上使用&GT; 32位。

现在,所有这一切的原因是X11是在需要运行的所有系统上长时间为32位的时间制作的,并且一直保持不破坏其API和ABI,我会引自this post

  

您必须将C API与基础X11对象分开。该   对象是32位(或16或8),并始终保持不变。这些   必须以某种方式映射到语言(C)。挑选的类型   很好地匹配了几十年,但不幸的是不再。   因此,而不是回避说“我们并不是真的意味着长,   我们的意思是什么类型 - 最接近32位 - 现在“,他们保持   长。其他任何事情都可能意味着非常痛苦   过渡期。

     

这意味着X11 API中处理32位的所有内容   对象将使用64位变量,浪费一半的空间。