如何在c程序中使用dialog.h

How to use dialog.h in a c program

我正在尝试在我的 C 程序中使用 dialog.h。为此,我查阅了手册 (man 3 dialog) 并使用了他们提供的示例代码。这是我的 C 程序的样子(它被称为 main.c):

#include <dialog.h>

int main(void)
{
  int status;
  init_dialog(stdin, stdout);
  status = dialog_yesno(
    "Hello, in dialog-format",
    "Hello World!",
    0, 0);
  end_dialog();
  return status;
}

经过研究我发现,dialog 程序是基于 ncurses。所以我已经安装了两个库,其中包含所需的头文件。

我正在开发 Debian,所以: apt install dialog libncurses5-dev libncursesw5-dev

下一步我调用了编译器,我也链接了库:gcc main.c -ldialog -lncurses


但是编译没有成功

/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(util.o): In function `dlg_auto_size':
(.text+0x1a06): undefined reference to `sqrt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(trace.o): In function `dlg_trace_win':
(.text+0x29c): undefined reference to `win_wch'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(trace.o): In function `dlg_trace_win':
(.text+0x2ab): undefined reference to `wunctrl'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x2c4): undefined reference to `_nc_wacs'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x2d6): undefined reference to `wadd_wch'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x43c): undefined reference to `_nc_wacs'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x44e): undefined reference to `wadd_wch'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_scrollbar':
(.text+0x878): undefined reference to `_nc_wacs'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_scrollbar':
(.text+0x88f): undefined reference to `wvline_set'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(inputstr.o): In function `dlg_index_columns':
(.text+0x932): undefined reference to `setcchar'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(inputstr.o): In function `dlg_index_columns':
(.text+0x93c): undefined reference to `wunctrl'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(ui_getc.o): In function `dlg_getc':
(.text+0x603): undefined reference to `wget_wch'
collect2: error: ld returned 1 exit status

经过研究我发现缺少对win_wchwunctrl等函数的引用都是在curses.h.

中定义的

关于此 post (What's the difference between -lcurses and -lncurses when compiling C using ncurses lib?) ncursescurses 相同,因为 curses 链接到 ncurses

但无论如何,我也尝试过使用 curses 库进行编译:gcc main.c -lcurses -lncurses -ldialog。但是也没用。

我错过了什么?为什么编译失败?

我在基于 Debian 的系统(Beaglebone)上做了一些测试,这不是一个明显的修复。原来有多个版本的 ncurses 库,对话框库是用 一个 构建的,而不是你使用的那个。

你应该用 dialog-config 命令来解决这个问题,它有选项可以显示你在编译行(或在 makefile 中)需要哪些 CFLAGS 或库,但我没有在我的系统上找不到它,所以我查看了 /usr/include/dlg_config.h 以获取一些线索:

...
#define DLG_HAVE_LIBINTL_H 1
#define DLG_HAVE_LIBNCURSESW 1   <---
#define DLG_HAVE_LIMITS_H 1

嗯,这表明它需要 -lncursesw 而不是 -lncurses,所以我们看到这个编译:

$ gcc dlg.c -ldialog -lncursesw
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf/libdialog.a(util.o): in function `dlg_auto_size':
(.text+0x13d2): undefined reference to `sqrt'

好的,所以更近了:sqrt() 在数学库中,所以添加 -lm 就可以越过球门线:

$ gcc dlg.c -ldialog -lncursesw -lm

看来 ncursesw 是一个宽字符版本,适用于国际字符集,这对我来说是新的。

编辑:详细说明 "dialog-config" 内容:dialog(3) 手册页中记录了您应该执行此操作的方式:

gcc $(dialog-config --cflags) file ... $(dialog-config --libs)

这个想法是一个包可以在一个命令中发布它需要构建的东西,所以在这种情况下我想 dialog-config --cflags 可能不会输出任何东西,但是 dialog-config --libs 会输出 -ldialog -lncursesw -lm,这样您就可以将它嵌入到您的 makefile 中并让它做正确的事情。

这种模式很常见,在我的系统上我看到(例如)/usr/bin/python-config 显示它是如何在这台机器上构建的:

$ python-config --cflags
-I/usr/include/python2.7 -I/usr/include/arm-linux-gnueabihf/python2.7
-fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g
-fdebug-prefix-map=/build/python2.7-RT6aMn/python2.7-2.7.16=.
-fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG
-g -fwrapv -O2 -Wall -Wstrict-prototypes

$ python-config --libs
-lpython2.7 -lpthread -ldl  -lutil -lm 

如果您尝试构建某种 Python 插件,猜测上述参数将是一个真正的挑战。