简体   繁体   English

Libicu,编译时未定义参考

[英]Libicu, undefined reference while compiling

I'm trying to use the lib icu in my shared library. 我正在尝试在共享库中使用lib icu。 So i generate my .so who use libicu functions, this parts works well. 因此,我生成了使用libicu函数的.so,这部分效果很好。

Then i try to compile my main program, using the shared library that i created before. 然后,我尝试使用之前创建的共享库来编译我的主程序。 But i get the following error: 但我得到以下错误:

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'

I have installed the libicu with this help. 我已经在帮助下安装了libicu。

I compile my shared library with -licuuc, as well as my main program compile only with -l:libstring.so and -licuuc. 我用-licuuc编译共享库,而我的主程序仅用-l:libstring.so和-licuuc编译。

When i do ldd libstring.so, i don't have the .so of the libicu on the list of dependencies. 当我执行libdd.so时,我在依赖项列表中没有libicu的.so。

The problem probably come from this. 问题可能来自此。

Thx 谢谢

EDIT: I have create a little test: 编辑:我创建了一个小测试:

icu.h: 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: 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: 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();
}

Makefile: 生成文件:

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"

Note: even with -licuuc instead of -licui18n i got the same error. 注意:即使使用-licuuc而不是-licui18n,我也会遇到相同的错误。

Output: 输出:

$> 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

If i do ldd on my shared library: 如果我在共享库上执行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: 编辑2:

Ok, seems that the problem is easier to solve than expected. 好的,似乎该问题比预期的要容易解决。 My program need function in icu_53, but i got icu_48 installed on my computer dunno why. 我的程序需要在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

Does anyone know how to upgrade the version from icu_48 to icu_53 at least ? 至少有人知道如何将版本从icu_48升级到icu_53吗?

Seems 'udat_parse_53' is located inside libicui18n.so.53 library. 似乎“ udat_parse_53”位于libicui18n.so.53库中。 Try to compile your project with '-licui18n' option. 尝试使用'-licui18n'选项编译您的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM