首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GraphicsMagick FFI发行

GraphicsMagick FFI发行
EN

Stack Overflow用户
提问于 2015-11-06 22:54:30
回答 2查看 161关注 0票数 1

作为练习,我尝试用Rust编写一个GraphicsMagick FFI包装器。我在复制一些引用C代码时遇到了问题:

演示C代码

代码语言:javascript
复制
Image
  *image = (Image *) NULL;
ImageInfo
  *imageInfo;
ExceptionInfo
  exception;

InitializeMagick(NULL);
imageInfo=CloneImageInfo(0);
GetExceptionInfo(&exception);

以下是我(天真的)对“锈”的翻译:

代码语言:javascript
复制
let img: *mut ffi::Image;
let img_info: *mut ffi::ImageInfo;
let exception: *mut ffi::ExceptionInfo = ptr::null_mut();
unsafe {             
  ffi::InitializeMagick(ptr::null_mut());
  img_info = 
    ffi::CloneImageInfo(ptr::null_mut() as *const ffi::ImageInfo);
  ffi::GetExceptionInfo(exception);
  // ...
}

这编译得很好,但是当我尝试运行它时,我发现:

代码语言:javascript
复制
magick/error.c:388: GetExceptionInfo: Assertion `exception != (ExceptionInfo *) ((void *)0)' failed

是由ffi::GetExceptionInfo(exception)引起的。唯一的区别似乎是C异常没有被“初始化”,但是我对C不太了解,不知道空/未初始化指针之间是否有区别。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-06 23:38:32

C代码和Rust代码之间的区别是,C版本在堆栈上分配一个ExceptionInfo实例,并将引用该实例的指针传递给GetExceptionInfo

另一方面,锈蚀代码传递一个NULL指针。

GetExceptionInfo专门防止传递NULL指针,您可以看到断言的代码这里,用magick/error.c

我不知道您使用哪种FFI绑定,但是如果在它们中完全定义了ExceptionInfo,那么您应该能够在堆栈上分配它并传递一个引用,就像在C版本中那样:

代码语言:javascript
复制
let mut exception: ffi::ExceptionInfo = unsafe {std::mem::uninitialized()};
unsafe {ffi::GetExceptionInfo (&mut exception);}
票数 4
EN

Stack Overflow用户

发布于 2015-11-06 23:33:59

错误消息声明(重写了一点):

断言exception != NULL失败

也就是说,不能将NULL传递给该方法。注意C代码:

代码语言:javascript
复制
ExceptionInfo exception;

这是而不是指针。您需要为它分配空间,然后传入对分配空间的引用。

文档显示了定义:

代码语言:javascript
复制
typedef struct _ExceptionInfo
{
  char
    *reason,
    *description;

  ExceptionType
    severity;

  unsigned long
    signature;
} ExceptionInfo;

你需要用铁锈来表示这一点。类似于这段未经测试的代码:

代码语言:javascript
复制
extern crate libc;

#[repr(C)]
struct ExceptionInfo {
    reason: *const libc::c_char,
    description: *const libc::c_char,
    severity: ExceptionType,
    signature: libc::c_ulong,
}

#[repr(C)]
enum ExceptionType {
    UndefinedException,
    WarningException = 300,
    // the rest
}

然后您需要分配它并传递一个引用。更多未经测试的代码:

代码语言:javascript
复制
let img_info;
let mut exception = ffi::ExceptionInfo::new();

unsafe {             
    ffi::InitializeMagick(ptr::null_mut());
    img_info = 
        ffi::CloneImageInfo(ptr::null_mut() as *const ffi::ImageInfo);
    ffi::GetExceptionInfo(&mut exception);
    // ...
}

注意,锈蚀样式是4个空格缩进。

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

https://stackoverflow.com/questions/33576978

复制
相关文章

相似问题

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