我使用其外部函数接口从Nim使用GNU argparse。 在<argp.h>中有函数argp_parse,声明如下
extern error_t argp_parse (const struct argp *__restrict __argp, int __argc, char **__restrict __argv, unsigned __flags, int *__restrict __arg_index, void *__restrict __input);棘手的部分是第一个参数之前的const和__restrict,在Nim中我编写了这段代码
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".}问题是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'的冲突类型”,我猜这是因为它在第一个参数中找到了具有不同类型的相同函数的两个定义。
有没有办法强制Nim编译器在使用c后端时在函数参数之前添加const(也许__restrict)关键字?
I am using GNU argparse from Nim using its foreign function interface. In <argp.h> there is function argp_parse which is declared as follows
extern error_t argp_parse (const struct argp *__restrict __argp, int __argc, char **__restrict __argv, unsigned __flags, int *__restrict __arg_index, void *__restrict __input);the tricky part are the const and __restrict before the first parameter, in Nim I wrote this code
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".}the problem is that the Nim compiler (with c backend) generates this line for argp_parse function (note the missing const and __restrict keywords before the first parameter)
N_CDECL(Error177010, argp_parse)(struct argp* argp0, int argc0, NCSTRING* argv0, unsigned int flags0, int* argindex0, void* input0);then, when gcc handles that file, it complains yelling "conflicting types for ‘argp_parse’", I guess this is because it finds two definitions of the same functions with different types in the first parameter.
Is there any way to force the Nim compiler to add the const (and maybe __restrict) keyword before a function parameter when using the c backend?
最满意答案
Nim将来会支持一个restrict编译指示,允许您指定这些参数。 从Nim存储库中最新的todo.txt可以看出这一点。
与此同时,有一种可能的解决办法。 您可以使用emit pragma而不是importc pragma:
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`);".}这将创建一个常规的非导入过程,只转发调用argp_parse函数。
Nim will support a restrict pragma in the future that will allow you to specify such parameters. This is evident from the latest todo.txt in the Nim's repository.
In the meantime, there is one possible work-around for this. Instead of using the importc pragma, you can use the emit pragma:
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`);".}This will create a regular non-imported proc that just forwards the call the argp_parse function.
更多推荐
发布评论