交叉编译的UTF8 ncurses显示错误

2024-06-28 10:54:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个嵌入式系统,有一个vt52u(unicode)终端仿真器,它可以正确显示UTF-8字符,但是我有交叉编译的程序(vim和python),在使用ncursesw库时,这些程序不能在终端上正确显示unicode字符。在

我已经做过搜索,但是网上没有什么有用的。。。在

Bash shell设置了以下变量:

LANG=en_US.UTF-8
LD_LIBRARY_PATH=/mnt/sd/lib  # all libraries, cross compiled, are located here
TERM=vt52u
TERMCAP='vt52u|vt52 with UTF-8:am:eo:rs=\Ee\Eb0\Eco:is=\EE\Ee:nl=^j:sr=\Ei:bl=^g:ta=^i:ho=\EH:cr=^m:le=\ED:nd=\EC:do=\EB:up=\EA:ta=^i:nw=^m:xn:cm=\EY%+ %+ :it#8:co#75:li#24:sc=\Ej:rc=\Ek:vi=\Ef:ve=\Ee:so=\Eb0\Ec4:se=\Eb0\Eco:mh=\Eb8\Eco:mr=\Ebo\Ec0:me=\Eb0\Eco:cl=\EH\EJ:cd=\EJ:ce=\EK:km:ku=^p:kd=^n:kr=^f:kl=^b:kb=^h:'
LOCALE=

我知道unicode终端很好,因为我可以运行以下程序让它完美地显示UTF-8字符。在

^{pr2}$

但是,当我试图在python程序中使用curses(ncursesw)来显示方框图字符,或者使用vim(它链接到ncursesw)编辑UTF-8文本文件时,我最终会在屏幕上打印出一个无效的unicode框,后面是额外的符号,如~T~B、~T~L,以及每个unicode字符的许多其他变体。因此,出于某种原因,ncursesw正在输出无效的UTF-8字符。。。。在

我知道它链接正确,并且没有冲突的ncurses库;只有ncursesw存在。在

我将ncurses-5.9库配置为如下编译:

./configure --prefix=/mnt/sd --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --without-curses-h --with-build-cc=gcc --with-shared --without-normal --without-debug --without-profile --without-gpm --without-dlsym --without-sysmouse --build=i686-linux --host=arm-linux-gnueabi --without-pthread --enable-widec --with-fallbacks=vt52 --with-terminfo-dirs=/etc/terminfo --disable-big-core --enable-termcap --with-termpath=/Data/termcap

例如:以下程序在我的桌面linux~VT102上运行良好,但在vt52u上运行时,嵌入式系统会出现故障:

#!/bin/env python
# coding=UTF-8
board=[
"","",
u"   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐",
u"   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │",
u"   │   │ ├───→───→───→ │   │   │   │   │   │ ├───→───→───→ │   │   │" ]

board = ( i.encode("utf-8") for i in board )

import curses
import locale
locale.setlocale( locale.LC_ALL,"" )

screen = curses.initscr()
curses.noecho() # no echoing
curses.cbreak() # no keyboard buffering

# Setup the playing board screen. 
for i,s in enumerate( board ): screen.addstr( i,0,s )
screen.refresh()

import time
time.sleep(2)

# Return everything to normal
curses.echo()
curses.nocbreak()
curses.endwin()

编辑:我发现了这个bug的一个可能的原因——glibc被交叉编译时,没有正确的路径到/mnt/sd/share/i18n/charmap或/mnt/sd/share/i18n/locales目录。它只有部分路径,这些路径的前缀是错误的“/”,而不是目标系统的实际根路径/mnt/sd。当找不到文件时,glibc显然默认返回“C”或“POSIX”区域设置并忽略环境变量。在

我不确定是否必须重新编译glibc并手动编辑makefile,或者是否有方法在构建系统后手动设置路径??有什么想法吗。 ??? 在


Tags: 路径程序board系统withunicodesd字符
1条回答
网友
1楼 · 发布于 2024-06-28 10:54:11

Ncurses依赖于标准C库,该库需要一个编译后的路径,指向包含国际化文件的目录,否则Ncurses将自动默认返回POSIX语言环境(也称为“C”语言环境),而不会执行UTF-8。在

在一个生成系统上,如果区域设置存储在与主机不同的位置,则交叉编译会导致自动配置脚本错误识别目录,然后即使正确设置了区域设置变量,嵌入式系统也无法执行UTF-8。。。更糟糕的是,失败可能不会生成错误消息。在

但是:如果路径错误,则在运行以下命令时,除了POSIX&C,您将无法看到任何区域设置:

locale -a

用国际化的文件在构建系统上建立一个虚拟目录,然后重新编译标准的C库是解决这个问题的一种方法;但它可能需要根权限。在

另外,在使用gnu标准C库(glibc)时,可以设置一个环境变量“I18NPATH”;它应该覆盖编译后的in路径。如果嵌入式系统上的安装前缀是“/mnt/sd”,那么在bash shell中只需执行以下操作:

^{pr2}$

在任何一种情况下,一旦纠正路径可用/安装,系统应正常运行。如果没有,请检查以确保确实为country charmap和UTF-8的组合生成了语言环境,这是所需的(使用“locale-a”将它们全部列出)。在

如果它不存在,可以非常简单地使用“localedef”实用程序创建它。例如:要创建支持UTF-8的美国英语区域设置,只需执行以下操作:

^{3}$

然后,确保已设置并导出区域设置变量:

export LOCALE=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

然后运行不带参数的locale应该将所有变量显示为en_美国UTF-8。。。从那以后一切都会好起来的。在

相关问题 更多 >