在Crystal lib中引用C枚举

我正在尝试围绕 libevent 编写一个Crystal包装器,我想知道如何处理其命名为全小写的枚举,例如:

枚举ev_http_request_error

我尝试了以下方法:

@[Link("event")]
lib LibEvent
  # <snip>
  enum evhttp_request_error
    EVREQ_HTTP_TIMEOUT,
    EVREQ_HTTP_EOF,
    EVREQ_HTTP_INVALID_HEADER,
    EVREQ_HTTP_BUFFER_ERROR,
    EVREQ_HTTP_DATA_TOO_LONG
  end
end

但这失败了,因为 evhttp_request_error 不适合Crystal常量的语法 . 我该如何解决这个问题?

回答(2)

2 years ago

您可以随意命名 . 但是当你在lib包装器中使用enum时,你只需要声明一个新的C enum:

@[Link("event")]
lib LibEvent
   enum EvHTTPRequestError
     EVREQ_HTTP_TIMEOUT
     EVREQ_HTTP_EOF
     EVREQ_HTTP_INVALID_HEADER
     EVREQ_HTTP_BUFFER_ERROR
     EVREQ_HTTP_DATA_TOO_LONG
  end
end

这实际上与:

@[Link("event")]
lib LibEvent
   enum EvHTTPRequestError
     EVREQ_HTTP_TIMEOUT = 0
     EVREQ_HTTP_EOF = 1
     EVREQ_HTTP_INVALID_HEADER = 2
     EVREQ_HTTP_BUFFER_ERROR = 3
     EVREQ_HTTP_DATA_TOO_LONG = 4
  end
end

并且此枚举中的值与原始C lib中的值不匹配 .

您需要在枚举中手动set (duplicate)正确值 .

由于Crystal只绑定到共享库文件,除了手动(有时会自动)将这些文件复制为Crystal代码中的常量之外别无选择 .

Checkout example in Crystal stdlib

2 years ago

简而言之,it doesn't matter . 这个名字并不是一个美化的int),所以如果这些值与C-land中的对应物相匹配,那么这个类型的Crystal名称可以是你想要的任何东西:)