2017-01-08 10 views
1

Nimの外部関数インタフェースを使用してGNU argparseを使用しています。 > argp.h <で Nimから構造体へのconstポインタを受け取るC関数を呼び出します。

extern error_t argp_parse (const struct argp *__restrict __argp, 
      int __argc, char **__restrict __argv, 
      unsigned __flags, int *__restrict __arg_index, 
      void *__restrict __input); 

トリッキーな部分はニムに私はこのコードを

type 
    ArgpChild {.importc: "struct argp_child"} = object 
    argp : ptr[Argp] 
    flags : cint 
    header : cstring 
    group : cint 

    Argp* {.importc: "struct argp", header: "<argp.h>"} = object 
    options : ptr[ArgpOption] 
    parser : pointer #proc (key : cint, arg: cstring, state : ptr[ArgpState]) : Error 
    args_doc : cstring 
    doc : cstring 
    children : ArgpChild 
    help_filter : pointer #proc(key : int, text : cstring, input: pointer) : cstring 
    argp_domain : cstring 

    ArgpOption* {.importc: "struct argp_option"} = object 
    name : cstring 
    key : cint 
    arg : cstring 
    flags : cint 
    doc : cstring 
    group : cint 

    ArgpState {.importc: "struct argp_state"} = object 
    input : pointer 

    Error* = enum 
    ARGP_KEY_ARG = 0, 
    ARGP_ERR_UNKNOWN = 7, 
    ARGP_KEY_END = 0x1000001 

proc argp_parse*(argp : Argp, argc : cint, argv : cstringArray, flags: cuint, arg_index: ptr[cint], input : pointer) : Error {.importc: "argp_parse".} 

書いて、最初のパラメータの前のconstと__restrictあり、以下のように宣言された機能argp_parseがあります問題は、Nimコンパイラ(cバックエンド付き)がargp_parse関数用のこの行を生成することです(最初のパラメータの前にconstキーワードと__restrictキーワードがありません)。

N_CDECL(Error177010, argp_parse)(struct argp* argp0, int argc0, NCSTRING* argv0, unsigned int flags0, int* argindex0, void* input0); 

gccがそのファイルを処理するときに、「argp_parse」の「競合する型」と叫んでいます。これは、最初のパラメーターで異なる型の同じ関数の2つの定義が見つかるためです。

cバックエンドを使用するときに関数パラメータの前にconst(および__restrict)キーワードを追加するようにNimコンパイラに強制する方法はありますか?

答えて

2

Nimは、このようなパラメータを指定できるようになる将来、restrictプラグマをサポートします。これは、Nimのリポジトリにある最新のtodo.txtから明らかです。

一方、これには回避策が1つあります。これは単なる呼び出しargp_parse機能を転送し、通常の非輸入PROCを作成します

proc argp_parse*(argp: Argp, 
       argc: cint, 
       argv: cstringArray, 
       flags: cuint, 
       arg_index: ptr[cint], 
       input: pointer): Error = 
    {.emit: "argp_parse(`argp`, `argc`, `argv`, `flags`, `arg_index`, `input`);".} 

:代わりにimportcプラグマを使用して、あなたはemitプラグマを使用することができます。

関連する問題