加载以下划线开头的符号

Loading symbols that begin with an underscore

我的 google-fu 在这个问题上很弱...(edit/spoiler:_ 毕竟不是问题,见下文)

为了提供一些背景信息,我正在使用 Nim 开发一个微型 可移植 程序。有一次,我想在 win32 上使用 getch()(使用旧的 windows XP)…

Nim 文档说:

proc getch(): char {.raises: [], tags: [].}
Read a single character from the terminal, blocking until it is entered. The character is not printed to the terminal. This is not available for Windows.

... 所以最终我使用了:

proc getch(): cint {.importc: "_getch", header: "<conio.h>".}

这很适合我的需要。但是后来,我尝试改用 dynlib pragma:

proc getch(): cint {.importc, dynlib: "msvcrt.dll".}

在 运行 时间失败:could not import: getch。那里没有魔法,符号应该以下划线开头!但是 _getch 甚至 `_getch` 在 Nim 中都是非法的。

(注意:据称 CRT 中有一个 getch,但 MS 告诉它已弃用,我们应该改用 _getch。)

为了确定,我用 Nim 不知道的 libc 符号尝试了同样的事情:

proc atoi(s: cstring): cint {.importc: "atoi", header: "<stdlib.h>".}

proc atoi(s: cstring): cint {.importc, dynlib: "msvcrt.dll".}

这两种情况都有效; atoi(显然)不以 _.

开头

在这种情况下,我现在可以使用 header pragma,但这是一个普遍的问题,我可能会再次面对,因此我的问题是:

如何使用 dynlibpragma 导入以 _ 开头的符号?

最好是在同一个 {. .} 中添加一个额外的编译指示,而不是在调用工具链时使用标志,但此时欢迎任何提示。我正在寻找不依赖外部库或其他语言的解决方案。

干杯。

(尼姆 0.13.0)

编辑:(以防其他人运行遇到同样的麻烦)

好的,所以我追错了问题。正如@flyx 所评论的那样,importc: "symbol" 可以与 dynlib 一起使用,就像在 header 中一样。问题是,我以前曾尝试过,但由于错误的原因而放弃了这种组合(因为 Nim 仍在大力开发中,有时我不得不猜测......这次不走运)。

事实上:

proc getch(): cint {.importc: "_getch", dynlib: "msvcrt.dll".}
proc kbhit(): cint {.importc: "_kbhit", dynlib: "msvcrt.dll".}

对我不起作用。不是在编译时,而是在 运行 时。

仍然没有:_getch 没有 return 直到我 Ctrl-C 它(也许这就是为什么它没有首先在 Windows 上实现的原因!)和在 _kbhit 上有一个循环,我需要终止任务。

proc getch(): cint {.importc: "_getch", header: "<conio.h>".}
proc kbhit(): cint {.importc: "_kbhit", header: "<conio.h>".}

做作业。

但是因为现在我测试成功了

proc atoi64(s: cstring): clonglong {.importc: "_atoi64", dynlib: "msvcrt.dll".}

我可以说下划线不是问题

使用:

proc getch(): cint {.importc: "_getch", dynlib: "msvcrt.dll".}