我有个问题因为我没办法了。我有一个用SWIG Package 的C库。我不使用FFI,因为我不想在我的GEM中有任何第三方依赖。问题是我遇到了一些问题。我在C中有一个函数,它创建char* buffer并返回它的大小。我需要返回ruby的缓冲区大小和缓冲区本身。使用size_t不是大问题,我可以在ruby端将其存储为int,并在返回C后对其进行强制转换,但我对char* 有问题。
当我把char* 从C返回到ruby时,它被转换为字符串。所以我不能再把它作为char* 返回给C。我试图做一些肮脏的事情,比如获取char* 的内存地址,将其存储为字符串并将其传递回C,但也不起作用。
什么是用例我需要使用第三方c库链接两个ruby线程。因此,我需要在线程1上创建链接示例,并将char* 和size_t指针传递给线程2,这是一个初始化链接。因此,没有改变这种做法的选择。
问题是,是否可以将引用传递给char* 指针C -> Ruby -> C以及如何做到这一点。我挖的解决方案,因为2天,但我没有好主意在这里。
Thx in advance:)
将char* 从C返回到Ruby的示例函数
char* link_rb() {
size_t in_process_link_size = 0;
link_create(NULL, 0, &in_process_link_size);
unsigned char* in_process_link = NULL;
if (in_process_link_size != 0) {
in_process_link = (unsigned char*)malloc(in_process_link_size);
if (in_process_link != NULL)
in_process_link_size = link_create(in_process_link, in_process_link_size, NULL);
}
return in_process_link;
}
link_create不是我的函数,我需要在这里使用它(不能更改它)。
另一方面,我需要做这样的事情:
tracer_handle_t tracer_create_rb(unsigned char const* link) {
size_t link_size = 40;
char* buffer = (char*) &link;
size_t tracer = inprocesslinktracer_create(link, link_size);
return tracer;
}
inprocesslinktracer_create也不是我的函数。来自SDK
让我们假设现在我只返回char*,并传递它以及单个参数。一般来说,我需要缓冲区的大小,我可以在这里进入结构,但首先我想在这里弄清楚。
1条答案
按热度按时间bt1cpqcv1#
问题是,是否可以将引用传递给char* 指针C -> Ruby -> C
是的
SWIG默认假设
char *
类型的对象应该被 Package ,以便给予访问指向的数据的权限,而不是指针本身。这与它处理其他指针的方式不同。但是,SWIG的Map行为可以通过Typemaps进行定制,并且在必要的时候,您可以通过编写一个shim来帮助它(这里的示例不需要)。示例代码可以使用简单的输入和输出类型Map:
mymodule.i
in
类型Map为匹配给定名称和数据类型的参数或对象指定Ruby -> C转换。类似地,out
类型Map为返回值或匹配给定名称和数据类型的对象指定了C -> Ruby转换。请注意,AS_NUMBER
仅具有该接口文件赋予的意义。这对SWIG来说并不特别。一般来说,我需要缓冲区的大小,我可以在这里进入结构,但首先我想在这里弄清楚。
随你便