当前位置:  技术问答>linux和unix

glibc源码问题

    来源: 互联网  发布时间:2017-05-29

    本文导语:  本帖最后由 caoshufengcao 于 2014-09-19 10:23:08 编辑 有一段代码不知道用了什么语法: wcrtomb函数的源码如下: 我对DL_CALL_FCT这个宏不大了解,这是用了什么语法? static mbstate_t state; size_t __wcrtomb (char *s, wchar_t wc, mbsta...

本帖最后由 caoshufengcao 于 2014-09-19 10:23:08 编辑
有一段代码不知道用了什么语法:
wcrtomb函数的源码如下:
我对DL_CALL_FCT这个宏不大了解,这是用了什么语法?

static mbstate_t state;

size_t
__wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
{
  char buf[MB_CUR_MAX];
  struct __gconv_step_data data;
  int status;
  size_t result;
  size_t dummy;
  const struct gconv_fcts *fcts;

  /* Set information for this step.  */
  data.__invocation_counter = 0;
  data.__internal_use = 1;
  data.__flags = __GCONV_IS_LAST;
  data.__statep = ps ?: &state;
  data.__trans = NULL;

  /* A first special case is if S is NULL.  This means put PS in the
     initial state.  */
  if (s == NULL)
      s = buf;
      wc = L'';
    }

  /* Tell where we want to have the result.  */
  data.__outbuf = (unsigned char *) s;
  data.__outbufend = (unsigned char *) s + MB_CUR_MAX;

  /* Get the conversion functions.  */
  fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
  __gconv_fct fct = fcts->tomb->__fct;
#ifdef PTR_DEMANGLE
  if (fcts->tomb->__shlib_handle != NULL)
    PTR_DEMANGLE (fct);
#endif

  /* If WC is the NUL character we write into the output buffer the byte
     sequence necessary for PS to get into the initial state, followed
     by a NUL byte.  */
  if (wc == L'')
    {
      status = DL_CALL_FCT (fct, (fcts->tomb, &data, NULL, NULL,
                                  NULL, &dummy, 1, 1));

      if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT)
        *data.__outbuf++ = '';
    }
  else
    {
      /* Do a normal conversion.  */
      const unsigned char *inbuf = (const unsigned char *) &wc;

      status = DL_CALL_FCT (fct,
                            (fcts->tomb, &data, &inbuf,
                             inbuf + sizeof (wchar_t), NULL, &dummy, 0, 1));
    }

  /* There must not be any problems with the conversion but illegal input
     characters.  The output buffer must be large enough, otherwise the
     definition of MB_CUR_MAX is not correct.  All the other possible
     errors also must not happen.  */
  assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT
          || status == __GCONV_ILLEGAL_INPUT
          || status == __GCONV_INCOMPLETE_INPUT
          || status == __GCONV_FULL_OUTPUT);

  if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT
      || status == __GCONV_FULL_OUTPUT)
    result = data.__outbuf - (unsigned char *) s;
  else
    {
      result = (size_t) -1;
      __set_errno (EILSEQ);
    }

  return result;
}




DL_CALL_FCT宏最后转化为如下:

status = (_dl_mcount_wrapper_check ((void *) (fct)), (*(fct)) (fcts->tomb, &data, &inbuf, inbuf + sizeof (wchar_t), ((void *)0), &dummy, 0, 1))


以下是DL_CALL_FCT的定义:

/* To support profiling of shared objects it is a good idea to call
   the function found using `dlsym' using the following macro since
   these calls do not use the PLT.  But this would mean the dynamic
   loader has no chance to find out when the function is called.  The
   macro applies the necessary magic so that profiling is possible.
   Rewrite
        foo = (*fctp) (arg1, arg2);
   into 
        foo = DL_CALL_FCT (fctp, (arg1, arg2));
*/
# define DL_CALL_FCT(fctp, args) 
  (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)


另外_dl_mcount_wrapper_check这个函数的返回类型是void它怎么能给status赋值呢?
这是用的gcc的什么特性吗?

|
就是简单的宏展开。
赋值给status的不是_dl_mcount_wrapper_check函数。你注意看一下括号。
status后面是个逗号分隔表达式,首先用_dl_mcount_wrapper_check检查 fct,然后调用fct将返回值赋给status。

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Linux下glibc库文件锁:协同锁(advisory lock)和强制锁(mandatory lock)
  • export LD_ASSUME_KERNEL=2.2.5 and . /usr/i386-glibc21-linux/bin/i386-glibc21-linux-env.sh
  • 我的glibc-doc中查不到sem_wait这样的函数 是我装的glibc-doc太旧么 不是阿 我是ubuntu上apt-get获得的应该最新了阿
  • linux与glibc
  • 嵌入式GLIBC EGLIBC
  • 无网,fedora core 13中glibc如何升级,或者共存?
  • 求助:安装glibc-2.3.6
  • 请问如何安装glibc-2.2 ?
  • 请问如何升级glibc
  • glibc和libc关系
  • 谁有glibc-2.3.2-5 rpms
  • 麻烦问一下怎么在cygwin下面安装glibc?
  • [求助] 如何升级GLIBC ???
  • 发布出去的程序,运行时总依赖glibc的版本怎么办??
  • glibc-headers 在哪里有下载的地方?急
  • 怎么裁剪linux下的glibc库函数
  • 如何将glibc-kernheaders安装上去
  • linux中的glibc库是不是只给应用程序调用的
  • 有关 glibc 的疑惑
  • glibc-2.5.9
  • 什么版本的linux系统 内置 glibc2.4以上的版本


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3