我正在尝试在共享库中使用lib icu。 所以我生成了使用libicu函数的.so,这部分效果很好。
然后我尝试使用我之前创建的共享库来编译我的主程序。但我得到以下错误:
release//libstring.so: undefined reference to `u_errorName_53'
release//libstring.so: undefined reference to `ucnv_toUnicode_53'
release//libstring.so: undefined reference to `ucnv_close_53'
release//libstring.so: undefined reference to `ucnv_fromUChars_53'
release//libstring.so: undefined reference to `udat_open_53'
release//libstring.so: undefined reference to `udat_parse_53'
release//libstring.so: undefined reference to `udat_format_53'
release//libstring.so: undefined reference to `ucnv_toUChars_53'
release//libstring.so: undefined reference to `ucnv_open_53'
release//libstring.so: undefined reference to `udat_close_53'
我已经使用this帮助安装了libicu。
我用-licuuc编译我的共享库,以及我的主程序只用-l:libstring.so和-licuuc编译。
当我执行ldd libstring.so时,我没有依赖列表中的libicu .so。
问题可能来自于此。
THX
编辑:我已经创建了一个小测试:icu.h:
#pragma once
#include <iostream>
#include <string>
#include <unicode/ucnv.h>
class c_icu
{
private:
void * p_priv;
public:
c_icu();
void open(const wchar_t *name);
void to_local(std::wstring &, std::wstring &);
void from_local(std::wstring &, std::wstring &);
void close(void);
~c_icu();
};
icu.cpp:
#include "icu.h"
c_icu::c_icu()
{
p_priv = NULL;
}
c_icu::~c_icu()
{
if (p_priv)
close();
}
void c_icu::open(const wchar_t *name)
{
UErrorCode status = U_ZERO_ERROR;
char conv_name[256];
if (wcstombs(conv_name, name, 256) == (size_t)-1)
{
std::cout << "ERROR: wcstombs failed" << std::endl;
exit(0);
}
if ((p_priv = (UConverter *)ucnv_open(conv_name, &status)) == NULL)
{
std::cout << "ERROR: ucnv_open failed" << std::endl;
exit(0);
}
}
void c_icu::to_local(std::wstring &src, std::wstring &dst)
{
UErrorCode status = U_ZERO_ERROR;
int32_t len;
len = ucnv_toUChars((UConverter *)p_priv, (UChar *)NULL, 0, (const char *)src.c_str(), src.size(), &status);
if (status == U_BUFFER_OVERFLOW_ERROR)
{
status = U_ZERO_ERROR;
dst.resize(len);
len = ucnv_toUChars((UConverter *)p_priv, (UChar *)dst.c_str(), dst.size(), (const char *)src.c_str(), src.size(), &status);
if (U_FAILURE(status))
{
std::cout << "ERROR: to_local failed" << std::endl;
exit(0);
}
}
}
void c_icu::from_local(std::wstring &src, std::wstring &dst)
{
UErrorCode status = U_ZERO_ERROR;
int32_t len;
len = ucnv_fromUChars((UConverter *)p_priv, (char *)NULL, 0, (const UChar *)src.c_str(), src.size(), &status);
if (status == U_BUFFER_OVERFLOW_ERROR)
{
status = U_ZERO_ERROR;
dst.reserve(len);
len = ucnv_fromUChars((UConverter *)p_priv, (char *)dst.c_str(), dst.size(), (const UChar *)src.c_str(), -1, &status);
}
}
void c_icu::close(void)
{
ucnv_close((UConverter *)p_priv);
p_priv = NULL;
}
TEST.CPP:
#include "icu.h"
int main(void)
{
c_icu converter;
std::wstring src = L"";
std::wstring dst;
const wchar_t add[11] = L"Just a test";
const wchar_t *unicode = L"koi8-r";
for (unsigned int i = 0; i < 1000; i++)
src.append(add, 11);
converter.open(unicode);
converter.from_local(src, dst);
converter.close();
}
生成文件:
NAME= test
LIB_NAME= libicutest.so
FLAGS= -W -Wall -Wextra
all: lib $(NAME)
$(NAME):
@echo "Main programm compiling ..."
g++ -c test.cpp -o test.o $(FLAGS)
g++ -o $(NAME) test.o -Wl,-rpath,'$$ORIGIN/' -licui18n -L. -licutest
@echo "Main programm compiled"
lib:
@echo "Lib Compiling ..."
g++ -std=gnu++11 -c -fPIC icu.cpp -o icu.o $(FLAGS)
g++ -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME) icu.o -licui18n
@echo "Lib Compiled"
注意:即使使用-licuuc而不是-licui18n,我也会遇到同样的错误。
输出:
$> make
Lib Compiling ...
g++ -std=gnu++11 -c -fPIC icu.cpp -o icu.o -W -Wall -Wextra
g++ -shared -Wl,-soname,libicutest.so -o libicutest.so icu.o -licui18n
Lib Compiled
Main programm compiling ...
g++ -c test.cpp -o test.o -W -Wall -Wextra
g++ -o test test.o -Wl,-rpath,'$ORIGIN/' -licui18n -L. -licutest
./libicutest.so: undefined reference to `ucnv_close_53'
./libicutest.so: undefined reference to `ucnv_fromUChars_53'
./libicutest.so: undefined reference to `ucnv_toUChars_53'
./libicutest.so: undefined reference to `ucnv_open_53'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
如果我在共享库上执行ldd:
$> ldd libicutest.so
linux-vdso.so.1 => (0x00007ffd5eb7f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f092b5e6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f092b221000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f092af1a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f092bb00000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f092ad04000)
EDIT2:
好吧,似乎问题比预期更容易解决。我的程序需要在icu_53中运行,但是我的计算机上安装了icu_48,为什么不知道。
$> locate libicu
/usr/lib/x86_64-linux-gnu/libicudata.so.48
/usr/lib/x86_64-linux-gnu/libicudata.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicui18n.so.48
/usr/lib/x86_64-linux-gnu/libicui18n.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicuio.so.48
/usr/lib/x86_64-linux-gnu/libicuio.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicule.so.48
/usr/lib/x86_64-linux-gnu/libicule.so.48.1.1
/usr/lib/x86_64-linux-gnu/libiculx.so.48
/usr/lib/x86_64-linux-gnu/libiculx.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicutest.so.48
/usr/lib/x86_64-linux-gnu/libicutest.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicutu.so.48
/usr/lib/x86_64-linux-gnu/libicutu.so.48.1.1
/usr/lib/x86_64-linux-gnu/libicuuc.so.48
/usr/lib/x86_64-linux-gnu/libicuuc.so.48.1.1
有没有人知道如何将版本从icu_48升级到icu_53至少?
答案 0 :(得分:0)
似乎'udat_parse_53'位于libicui18n.so.53库中。尝试使用'-licui18n'选项编译项目。