我在libelf库的libelf.h
的第153-154行找到了以下代码:
/* Descriptor for the ELF file. */
typedef struct Elf Elf;
我正在寻找Elf
的结构定义,但没有找到它。
稍后在代码中使用Elf
,例如
/* Return descriptor for ELF file to work according to CMD. */
extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);
在帖子Why should we typedef a struct so often in C?中,用户"放松"表示:
另请注意,虽然您的示例(和我的)省略了命名
struct
本身,实际命名它也适用于你想提供一个>不透明的类型。然后你在标题中有这样的代码,例如:
typedef struct Point Point;
Point * point_new(int x, int y);
然后在实现文件中提供
struct
声明。
然而,我无法在任何c文件中找到结构Elf
的定义。
我错过了什么?没有结构定义的typedef struct Name_xy Name_xy;
的目的是什么?或者这是不可能的,我只是没有找到结构定义?
修改
首先,感谢您的无数精彩回复。由于我的问题是双重的(至少),有两个答案:
lib/private.h
文件(感谢@molbdnilo指出定义在那里)。我安装了elfutils
而不是libelf
的来源。似乎private.h
源代码包中未包含elfutils
。答案 0 :(得分:3)
在C ++中,struct Elf
应该足以声明类型,这是返回指向该类型的指针所必需的。这通常是为了隐藏头文件用户的实现,这些用户本身不会使用Elf
功能,但可能只是传递指针。以这种方式编码可以消除对实际使用的头文件的不必要的依赖性。这种最小化头依赖关系的方法会对大型C ++项目中的编译时间产生很大影响。
正如其他人所提到的,typedef struct Elf Elf
是一个C事物,允许你在将来的声明中忽略struct
。
答案 1 :(得分:3)
typedef struct Elf Elf;
是一种简短的写作方式:
struct Elf;
typedef struct Elf Elf;
这些行做了不同的事情。第一个通常称为前向声明。这意味着我们以后可以使用以下代码:
// function prototype
struct Elf *elf_begin( stuff.... );
该函数原型化一个函数,该函数返回指向struct Elf
的指针,即使我们实际上并不知道struct Elf
正文中包含的内容。这有时称为 opaque类型,而C标准库中的另一个实例是FILE *
。任何地方都可能没有struct Elf
的定义。
正如您在问题中所说,第二部分typedef struct Elf Elf;
主要是避免必须始终键入struct
。
答案 2 :(得分:1)
是否在decl.h中定义了?
例如:
http://www.opensource.apple.com/source/dtrace/dtrace-96/head/libelf.h http://www.opensource.apple.com/source/dtrace/dtrace-118/libelf/decl.h
答案 3 :(得分:0)
可能的解释可能是您的项目有一些预编译的库文件,其中包含<p id="storyStarter" onclick="document.getElementById("storyStarter").innerHTML=""; printLetterByLetter("storyStarter"," It all begins here",50)">Click To begin Story</p>
<a onclick="empty("storyStarter")">Clear Text</a>
的定义。
答案 4 :(得分:0)
我错过了什么? typedef结构的目的是什么Name_xy Name_xy;没有结构定义?或者这是不可能的,我只是没有找到结构定义?
在libelf.h中,您有一个不透明类型的声明:Elf。
但是,您没有找到Elf结构的定义,而您想知道原因。
首先,某处有一个定义,它看起来像 struct Elf {...}; ,但是,由于开发人员无法访问该定义不希望你访问它。你可以使用Elf结构内容的唯一方法是因为在libelf.h中有这个声明, typedef struct Elf Elf; 。顺便说一句, struct Elf; 完全相同,但是使用typedef,我们知道该类型更不可能是不透明的。
一个更加举例说明的例子:
标题文件:
/* libelf.h */
typedef struct Elf Elf;
extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);
etc...
实施档案:
/* libelf.c */
struct Elf {
char * something;
FILE * whatever;
};
Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref){
/*doing something;*/
/* ... */
}
etc...
这正是封装的原则。此类型的内容是已知的,只有API函数的实现才可访问,客户端(您)无法直接访问其内容。对于开发人员来说,他们必须编译一个共享库,所以你可能会在某个地方找到像libelf.so这样的东西(我不知道自己做了什么,所以我无法帮助你)。 关于封装的目的,我建议你阅读this。
我没有别的想法,但如果你有更多问题,请不要犹豫。