【问题标题】:Compiled languages basics编译语言基础
【发布时间】:2010-11-28 00:17:09
【问题描述】:

请问,有人可以向我解释一些有关使用 C 等语言的基本知识吗?尤其是在 Windows 上?

  1. 如果我想使用其他库,我需要从库中获得什么?头文件 .h 和 ..?

  2. .dll 和 .dll.a. 有什么区别? .dll 和 .lib? .dll 和 .exe? .def 是什么?

  3. 库的编译方式是否重要?我的意思是,是否可以在 Windows 上从 MinGW 编译的 C 代码中使用 VC 编译的 C++ 库?

  4. 要使用另一个库,首选的方法是什么? LoadLibrary() 或 #include ?

  5. 有些库只提供源代码或.dll - 如何使用这些库?每次重建项目时都必须重新编译它们吗?

  6. 如何创建一个大的 .exe?这叫“静态链接”吗?

  7. 如何在 .exe 中包含一些随机文件?说出程序图标或启动歌曲?

  8. 如何将巨大的 .c 拆分成更小的文件?我是否需要为每个部分创建一个头文件,然后使用 WinMain() 或 main() 将其包含在该部分中?

  9. 如果有一个库需要另一个库,是否可以将这两个库合并到一个文件中?说,python26.dll 需要 msvcr90.dll 和 Microsoft.VC90.CRT.manifest

  10. 如果我不释放以前分配的内存会怎样?如果程序(进程)死了,这会被清理吗?

好吧,这么多问题...感谢您提供的每一个信息!

【问题讨论】:

  • SO 强烈建议每个问题问一个问题。这样做会给任何潜在的响应者带来相当大的负担。
  • 我认为你不应该在一条记录中问 10 个问题
  • 每个问题都需要太多的答案。你最好先阅读一本关于 C 编程的书,然后单独提出具体问题。
  • 如果每个问题都可以用一句话回答,那么最好不要有 10 个不同的问题。
  • 我同意 ChrisW 的观点,并这样对待它,但我完全不确定这是 Anton 的意图。

标签: c dll


【解决方案1】:

1:如果我想使用其他库,我需要从库中获得什么?头文件 .h 和 ..?

...通常是*.lib 文件,您将其作为参数传递给链接器。

2:.dll 和 .dll.a. 有什么区别? .dll 和 .lib? .dll 和 .exe? .def 是什么?

这可能有用:Static libraries, dynamic libraries, DLLs, entry points, headers … how to get out of this alive?

3:库是如何编译的有关系吗?我的意思是,是否可以在 Windows 上从 MinGW 编译的 C 代码中使用 VC 编译的 C++ 库?

是的,这很重要。对于编译器之间的互操作,通常的方法是使用具有明确定义的参数传递约定(例如__stdcall)的 C 风格(不是 C++ 风格)API,或者使用“COM”接口。

4:要使用另一个库,首选的方式是什么? LoadLibrary() 或 #include ?

#include 用于编译器(例如,它可以编译对库的调用); LoadLibrary(或者,使用 *.lib 文件)用于运行时链接器/加载器(以便它可以将这些库方法的实际地址替换到您的代码中):即您需要两者。

5:有些库只提供源代码或.dll - 如何使用这些库?每次重建项目时都必须重新编译它们吗?

如果它只是源代码,那么您可以(一次)将该源代码编译到一个库中,然后(在构建项目时)链接到该库(无需重新编译该库)。

6:如何创建一个大的.exe?这叫“静态链接”吗?

是的,编译所有内容并将其全部传递给链接器。

7: 如何在.exe 中包含一些随机文件?说出程序图标或启动歌曲?

在特定于 Windows 的“资源文件”中定义它,该文件由“资源编译器”编译。

8:如何将我的大 .c 拆分成更小的文件?我是否需要为每个部分创建一个头文件,然后使用 WinMain() 或 main() 将其包含在该部分中?

是的。

9:如果有一个库需要另一个库,是否可以将这两个合并到一个文件中?说,python26.dll 需要 msvcr90.dll 和 Microsoft.VC90.CRT.manifest

我不明白你的问题/例子。

10: 如果我不释放之前分配的内存会怎样?如果程序(进程)死了,这会被清理吗?

是的。

【讨论】:

  • 关于 9:假设我正在编写一个需要库 A 的程序,而库 A 又依赖于库 B。是否可以将 A 和 B 组合到 C,所以我只需要分发 C?我知道这样做可能没有意义,我要问的是是否可以合并 .dll?
  • 您也许可以组合静态库(并不是说有多大意义),但我认为您不能组合 DLL ......除非您有这些 DLL 的源代码,在这种情况下您可能可以将它们重建为单个 DLL。
【解决方案2】:

如果我想使用其他库,我需要从库中获得什么?头文件 .h 和 ..?

对于 C、C++,您需要头文件 .h 或 .hpp,尽管有些语言不需要头文件。您还需要 .a、.so、.dll、.lib、.jar 等文件。这些文件包含链接器可以链接到程序中的机器代码。不用说,链接器必须理解库的格式。

.dll 和 .dll.a. 有什么区别? .dll 和 .lib? .dll 和 .exe? .def 是什么?

dll 和 .a 是库文件,其中包含可以链接到自己程序中的代码组件。 a .exe 是已链接 .a 或 .dll 的最终程序。

库是如何编译的重要吗?我的意思是,是否可以在 Windows 上使用由 VC 从 MinGW 编译的 C 代码中编译的 C++ 库?

是的,您使用的库必须与您的平台兼容,这一点很重要。通常 Unix 库不会在 Windows 上运行,反之亦然,如果你使用的是 JAVA,你会更好,因为 .jar 文件通常可以在任何启用 JAVA 的平台上运行(尽管版本很重要)

要使用另一个库,首选的方法是什么? LoadLibrary() 或 #include ?

include 不是一种使用库的方法,它只是一个预处理器指令,告诉您预处理器在当前源文件中包含外部源文件。该文件可以是任何文件,而不仅仅是 .h,尽管通常它是 .h 或 .hpp 最好不要让我决定何时将库加载到运行时环境或链接器,除非您确定在特定时间点加载库会为您的代码增加一些价值。执行此操作的性能成本和确切方法取决于平台。

有些库只提供源代码或.dll - 如何使用这些库?每次重建项目时都必须重新编译它们吗?

如果您有源代码,则每次对其进行更改时都需要重新编译它。 但是,如果您无论如何都没有更改库的来源,则无需重新编译它。像 Make 这样的构建工具足够智能,可以为您做出这个决定。

如何创建一个大的 .exe?这叫“静态链接”吗?

创建静态 .exe 取决于您使用的构建工具。 使用 gcc 这通常意味着您必须使用 -static 选项 gcc -static -o my.exe my.c

如何在 .exe 中包含一些随机文件?说出程序图标或启动歌曲?

编程中没有什么是随机的。如果是我们就麻烦了。同样,您播放歌曲或显示图标的方式取决于您在某些平台上使用的平台,甚至可能无法这样做。

如何将巨大的 .c 拆分成更小的文件?我是否需要为每个部分创建一个头文件,然后使用 WinMain() 或 main() 将其包含在该部分中?

您需要一个包含所有函数原型的头文件,并且可以将程序拆分为多个包含一个或多个函数的 .c 文件。您的主文件将包括头文件。所有源文件都需要单独编译,然后链接到一个可执行文件中。通常,您会为每个 .c 获得一个 .o,然后将所有 .o 链接在一起以获得一个 .exe

如果有一个库需要另一个库,是否可以将这两个合并到一个文件中?说,python26.dll 需要 msvcr90.dll 和 Microsoft.VC90.CRT.manifest

是的,一个库可能需要另一个库,但是不建议将不同的库打包在一起,您可能违反了 IPR,而且每个库通常都是具有特定目的的定义良好的单元,并且通常将它们组合成一个没有多大意义。

如果我不释放之前分配的内存会怎样?如果程序(进程)死了,这会被清理吗?

再次取决于平台,通常在大多数操作系统上,内存会在程序终止后恢复,但在某些平台上,如嵌入式系统,它可能会永久丢失。 清理程序使用的资源总是一个好主意。

【讨论】:

  • 感谢您的详细解答!
【解决方案3】:

说真的,学习如何运行本地环境的地方是本地环境的文档。毕竟我们甚至不知道你的环境是什么,更不用说我们面前了。

但这里有一些答案:

1. 您需要标题和某种可链接对象。或者您需要源代码才能构建这些。

3. 库采用链接器可以理解的格式很重要。在 c++ 和其他语言中,它还需要理解所使用的名称修饰。

6. 强制所有库代码包含在可执行文件中,实际上称为“静态链接”。

7.at least one * question on "resource compilers"

【讨论】: