QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1146|回复: 14

请教高手:一个关于C程序函数调用的问题!

[复制链接]
发表于 2004-3-23 15:20:32 | 显示全部楼层 |阅读模式
有两个文件foo.c和foo.h,它们在逻辑上构成一个模块。
    foo.c中定义并实现了20个static函数,其中18都是被同文件中的其它函数内部引用了,最后,foo.c文件中只剩下两个函数foo_a_init()和foo_b_init()没有被引用,这两个函数不仅在foo.c内部没有被任何函数引用,在同一个软件包内的其它函数中也没有被引用(因为是static函数,所以也根本不可能被任何外部函数引用)。
    foo.h文件中定义了一个只有头,而没有具体实现体的函数foo_c()。外部对于foo模块唯一的引用就是在bar.c文件中引用了foo_c()。
    但是通过打印程序中间过程发现,foo_a_init()和foo_b_init()实际上都被调用了。
    现在怀疑,整个调用过程是不是这样:
        foo.h文件中定义foo_c()是foo模块对外界的接口。外部函数调用这个空函数就进入了对foo模块的调用,就会自动调用foo.c中的    foo_a_init()和foo_b_init()。
    但是,没有函数体的空函数(foo_c())为什么可以被调用?
    foo.c和foo.h又是怎么建立联系的?难道只是因为foo.c开头 #include "foo.h"吗?
    程序怎么知道去调用foo_a_init()和foo_b_init()?
发表于 2004-3-23 16:01:59 | 显示全部楼层
打印程序中间过程发现

您是在 gdb 里用 bt 看的么?重新编译再链接也是这样么? 编译时有没有加 -Wall 选项?建议加上再看看有没有错误或者警告。

程序怎么知道去调用foo_a_init()和foo_b_init()?

我认为您的程序不会自作主张调用 foo_a_init() 和 foo_b_init()
回复

使用道具 举报

 楼主| 发表于 2004-3-23 16:10:06 | 显示全部楼层
打印中间过程是通过在foo_a_init()和foo_b_init()中加入打印语句实现的,
这两个函数肯定是被引用了,因为运行结果已经显示了在foo模块中实现的功能。
而且整个软件编译、安装的过程中没有任何错误。

我也认为程序是不可能子做主张调用任何函数的,但是在整个软件源码包中都找不到
foo_a_init() 和 foo_b_init()的调用入口,但是它们又确实被调用了,这才奇怪啊
回复

使用道具 举报

发表于 2004-3-23 16:17:50 | 显示全部楼层
建议用 gdb 或者 ddd 什么的调试一下,如果我能帮您调试的话,可以站内发信给我。
回复

使用道具 举报

发表于 2004-3-23 17:45:44 | 显示全部楼层
楼主是在看别人的代码吧? 就楼主的描述来看,这是个典型的动态装配函数的过程吧
一个空的函数指针,具体用的时候指向一个函数,这些函数被设为静态避免直接的调用
回复

使用道具 举报

 楼主| 发表于 2004-3-24 11:05:08 | 显示全部楼层
[quote:ceafeaa751="wsm"]这是个典型的动态装配函数的过程吧
一个空的函数指针,具体用的时候指向一个函数,这些函数被设为静态避免直接的调用[/quote]

  我确实是在看他人代码

foo_c()函数被调用的时候的形式是:  
  bar(foo_c()); //bar为一个函数,它唯一的参数的类型就是foo_c()返回值的类型
  
  foo_c()并不是作为函数指针被调用的,也没有用g_signal_connect()把它和任何函数连接起立。如果说是动态装配函数的话,foo_c()是如何指向foo_a_init()和foo_b_init()的呢?
回复

使用道具 举报

发表于 2004-3-24 11:31:27 | 显示全部楼层
那你把具体代码贴上来 再看看
回复

使用道具 举报

发表于 2004-3-24 14:05:51 | 显示全部楼层
如果源代码太长,可以简化后试试,如果还是同样结果,把源码贴出来才能看得清楚
回复

使用道具 举报

 楼主| 发表于 2004-3-24 15:22:29 | 显示全部楼层
foo.h文件:

TypeOne      foo_c(void);
--------------------------

foo.c文件:

#include <config.h>
#include <string.h>

#include "foo.h"

static void func_1()
{
  ……
}

static void func_2()
{
  ……
}

……  ……
……  ……

static void func_18()
{
  ……
}


static void foo_a_init()
{
  func_1()
  func_2()
  ……     
  func_15()
}

static void foo_b_init()
{
  func_16()
  ……
  func_18()
}

//func_1()到func_18()这18个函数分别被foo_a_init()和foo_b_init()引用

--------------------------


foobar.c文件:

#include foo.h

…… ……

void one_func_of_foo_bar()
{
  ……
  bar(foo_c());
  ……
}

…… ……

void bar(TypeOne one)
{
   ……
   g_object_new( one, NULL);
   ……
}

…… ……
--------------------------
回复

使用道具 举报

 楼主| 发表于 2004-3-25 14:29:36 | 显示全部楼层
up 求教高手啊~~~
回复

使用道具 举报

 楼主| 发表于 2004-3-29 18:04:00 | 显示全部楼层
已经贴出几个函数的调用关系了,怎么还没有高手回答啊 :-(
回复

使用道具 举报

发表于 2004-3-29 19:42:45 | 显示全部楼层
这样的话 我是不知道怎么编译通过的了
回复

使用道具 举报

发表于 2004-3-29 22:35:58 | 显示全部楼层
假如仅仅是上述代码,谁敢说它能通过编译?兄弟,你这样不是折磨版主吗?(幸好我不是)

幸好还有一个g_object_new,知道你大概在看什么,那些满篇的bar,foo拜托你写清楚点嘛,如果你在看GObject的源代码,我想两位版主功力深厚,总能给你点提示吧?

还好还有一个init,你不如看看这个:

http://le-hacker.org/papers/gobject/index.html
回复

使用道具 举报

 楼主| 发表于 2004-3-31 11:32:05 | 显示全部楼层
诸位大哥~~我这么写只是为了尽量简单清晰,全都用原函数名,干脆就贴个源码包算了。   :-(
回复

使用道具 举报

发表于 2004-3-31 12:07:22 | 显示全部楼层
不好意思,我想你也是花了时间更好地陈述你的问题。
不过你的那个“概括”的确没什么用(除了让wsm睡不着觉)。你想,就你那几个函数定义,没有foo_c的实现,违反了基本的语法吗,是吧?
这儿有许多象wsm、两位版主等一样的高手。我想你的问题涉及某个方面,如果你能对你的问题再明确些,大家总能有点办法吧?
比如,也许在某个库里(正好你链接了)实现了那个没有函数体的在GObject中称之为”纯虚函数“(GOject借用的面向对象的术语)的东西?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 16:40 , Processed in 0.074429 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表