在 Crystal 库中引用 C 枚举

Referencing C enums in a Crystal lib

我正在尝试围绕 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 常量的语法。 我应该如何解决这个问题?

简而言之,it doesn't matter。该名称不需要与 C 名称完全匹配(无论如何它是一个美化的 int),因此只要 values 与 C-land 中的对应名称相匹配,Crystal该类型的名称可以是任何你想要的:)

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

@[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 库中的值不匹配。

您需要 手动更正枚举中的值。

Since Crystal only binds to a shared library file, there is no option other than manually (sometimes automatically) duplicating these as constants in Crystal code.

Checkout example in Crystal stdlib