首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于OCaml的MIT绑定

用于OCaml的MIT绑定
EN

Stack Overflow用户
提问于 2012-11-22 15:47:20
回答 1查看 219关注 0票数 1

我正在尝试用绑定奥卡米尔-西利卜来扩展MIT-SHM扩展。这是我第一次尝试将C与OCaml接口,我从未用C编写过任何东西,所以我想我在某个地方做了一些愚蠢的事情。

我首先添加了XShmQueryExtension函数。我在Xlib.ml文件中添加了以下内容

代码语言:javascript
复制
external xShmQueryExtension: dpy:display -> bool = "ml_xShmQueryExtension"

wrap_xlib.c文件的以下内容

代码语言:javascript
复制
CAMLprim value
ml_xShmQueryExtension( value dpy )
{
  int ans = XShmQueryExtension( Display_val(dpy) );
  return Val_bool(ans);
}

我将Makefile更改为与Xext链接,它起作用了:当我从xShmQueryExtension调用OCaml函数时,我得到了真。

现在,我正在编写一个创建共享xImage的函数,初始化共享内存并将其附加到X服务器。我在Xlib.ml文件中添加了以下内容:

代码语言:javascript
复制
type xShmSegmentInfo

external xShmCreateImageAndAttach:
  dpy:display -> visual:visual -> depth:int -> fmt:ximage_format
  -> width:uint -> height:uint -> xShmSegmentInfo * xImage
    = "ml_xShmCreateImageAndAttach_bytecode"
      "ml_xShmCreateImageAndAttach"

以及wrap_xlib.c文件中的以下内容:

代码语言:javascript
复制
#define Val_XShmSegmentInfo(d) ((value)(d))
#define XShmSegmentInfo_val(v) ((XShmSegmentInfo *)(v))

CAMLprim value
ml_xShmCreateImageAndAttach( value dpy, value visual, value depth, value format,
                             value width, value height)
{
    CAMLparam5(dpy, visual, depth, format, width);
    CAMLxparam1(height);
    CAMLlocal1(ret);

    XShmSegmentInfo *shminfo = malloc(sizeof(XShmSegmentInfo));

    XImage *ximage = XShmCreateImage(
        Display_val(dpy),
        Visual_val(visual),
        Int_val(depth),
        XImage_format_val(format),
        NULL,
        shminfo,
        UInt_val(width),
        UInt_val(height)
    );
    shminfo->shmid = shmget (IPC_PRIVATE,
      ximage->bytes_per_line * ximage->height, IPC_CREAT|0777);
    shminfo->shmaddr = ximage->data = (char *) shmat (shminfo->shmid, 0, 0);
    if (shminfo->shmaddr == -1)
      fprintf(stderr,"Error");
    shminfo->readOnly = False;
    XShmAttach (Display_val(dpy), shminfo);

    ret = caml_alloc(2, 0);
    Store_field(ret, 0, Val_XShmSegmentInfo(shminfo) );
    Store_field(ret, 1, Val_XImage(ximage) );
    CAMLreturn(ret);
}

CAMLprim value
ml_xShmCreateImageAndAttach_bytecode( value * argv, int argn )
{
    return ml_xShmCreateImageAndAttach(argv[0], argv[1], argv[2], argv[3],
                                       argv[4], argv[5]);
}

现在,我在我的OCaml程序中调用这个函数:

代码语言:javascript
复制
let disp = xOpenDisplay ""
let screen = xDefaultScreen disp
let (shminfo, image) = xShmCreateImageAndAttach disp
  (xDefaultVisual disp screen)
  (xDefaultDepth disp screen) ZPixmap 640 174

这是我的OCaml程序中的toplevel调用,我再也不会使用变量shminfo和image (这只是为了测试函数是否工作)。这个调用不会失败,但我的程序段故障发生了一段时间后(我的程序的其余部分经常用xGetImage转储屏幕并对像素进行处理,并且在某些xGetPixel中得到一个分段错误,这与上面对xShmCreateImageAndAttach的调用无关)。我注意到,如果删除行shminfo->shmaddr = ximage->data = (char *) shmat (shminfo->shmid, 0, 0);,我就不会再得到分段错误了(当然,这不能满足我的要求)。

我认为这与垃圾收集器有关,但我不知道如何修复它。在OCaml文档上,有一个关于将使用malloc获得的指针转换到值类型的警告,但我并不真正理解它的含义,也不知道它是否相关。

编辑:

我将shmat后面的两行替换为:

代码语言:javascript
复制
fprintf(stderr,"%i\n",(int)shminfo->shmaddr);
fflush(stderr);

我得到了类似于1009700864的东西,所以对shmat的调用似乎在起作用。

以下是gdb给出的回溯:

代码语言:javascript
复制
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7acdde8 in ?? () from /usr/lib/libX11.so.6
(gdb) backtrace
#0  0x00007ffff7acdde8 in ?? () from /usr/lib/libX11.so.6
#1  0x000000000044070c in ml_XGetPixel ()
#2  0x00000000004165b9 in camlInit__rvb_at_1023 () at init.ml:43
#3  0x0000000000415743 in camlParse__find_guy_1046 () at parse.ml:58
#4  0x000000000041610c in camlParse__pre_parse_1044 () at parse.ml:95
#5  0x0000000000415565 in camlGame__entry () at game.ml:26
#6  0x00000000004141f9 in caml_program ()
#7  0x000000000045c03e in caml_start_program ()
#8  0x000000000044afa5 in caml_main ()
#9  0x000000000044afe0 in main ()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-22 16:53:42

如果X要在您要转换为free()类型的shminfo指针上调用value,则警告是相关的。问题是,OCaml假设值可以由GC在以后自由复制和处理。对于指针值来说不是这样,因此可能会有指针的悬空副本。而且,这个空间可以作为OCaml堆的一部分被重用,这样您就会遇到真正的麻烦。

在我看来,X不会这么做,而且由于您没有在代码中调用free(),所以我不认为这是问题所在。但可能是.我不知道X是怎么工作的。

在调用fflush(stderr)之后打电话给fprintf()可能更好。它可能不会改变任何事情,但我发现我的跟踪消息往往会被缓冲,在程序崩溃时永远不会出现。

如果知道分段错误地址是什么样子也是很好的。在0附近吗?或者是堆中间的一个大地址?

对不起,我找不到你的错误。假设Display_val和其他代码正确工作,在阅读了4或5次代码之后,我没有看到您做错了什么。但这件事很难纠正。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13516146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档