2009-08-14 80 views
8

使用Visual Studio 2008及其C/C++编译器,如何创建仅依赖于其他Windows DLL的Win32 DLL,并且不依赖于微软C运行时?如何在不依赖C运行库的情况下创建Win32 DLL

我有一些C代码,我想放在一个完全计算的DLL中,并且几乎不使用C库函数。

对于那些使用(例如memcpy)的用户,我很高兴重写代码以使用Win32 API等价物(例如CopyMemory)。

+0

CopyMemory不是一个winapi函数,你将不得不自己编写 – Anders 2009-08-16 01:04:20

+6

不好意思碰到一个旧的线程,但'CopyMemory'是一个API函数:http://msdn.microsoft.com/en-us/library/ aa366535%28VS.85%29.aspx 除了'#define'd代替调用'memcpy'外。 – Thomas 2009-10-02 17:24:55

回答

10

使用/ NODEFAULTLIB链接器选项和(当然)确保您在运行时没有实际的依赖关系。您还需要指定&使用/ ENTRY链接器选项为DLL定义自己的入口点,或者使用自己的入口点函数来匹配编译器/链接程序所需的名称(对于dll,即_DllMainCRTStartup)。

从方式马特·皮特里克的文章后面,当上LIBCTINY可能将所有您需要的信息:

+0

引用那篇文章“幸运的是,我们已经过去了那些日子,在大多数情况下,您可以依靠目标机器上的MSVCRT.DLL。” Pietrek建议你应该如此依赖。 – 2009-08-14 19:29:39

+0

这是*仍然是真的*?自Windows 2000以来,许多方面都发生了变化。现在我认为我们不应该依赖MSVCRT。至少它比马特的声明表明更复杂。 – Cheeso 2009-08-24 03:27:15

+2

我们可以依赖MSVCRT.dll在机器上,但Visual C++链接针对MSVCRver.dll,其中ver是80,90,100,110等。 – BCran 2012-09-11 16:28:07

0

某些Windows库依赖于C运行库(例如ODBC32.DLL) 所以我认为你在这里隐藏到什么都没有。无论如何,你为什么要这么做?

+3

我认为它公平地假设windows dll的任何依赖关系都会随窗口一起提供。我没有看到你的观点。 – 2009-08-14 18:33:39

+0

如果你的代码依赖于ODBC32这样的DLL,那么它间接依赖于Windows自带的CRT--你错误的印象是它必须分开发布吗?如果你低估了这个答案,我必须问 - 为什么? – 2009-08-14 18:38:03

+0

如果我用微软C编译器构建我的代码,我必须使用它随附的C运行时,如果我想要他们记录/支持的行为。这需要用我的代码分发所述运行时。 我想我可以'发现'另一个C运行库在Windows中敲入并以某种方式动态链接到它,但是这比我想象的要更加努力,尤其是当我实际上不需要它的任何功能时... – 2009-08-14 19:01:05

0

使用静态微软库进行编译。

+2

正如此处所述:http://msdn.microsoft.com/en-us/library/abx4dbyh(VS.80).aspx 现代微软C运行时最好不是静态链接到系统中的其他库的dll可能正在使用C运行时。 – 2009-08-14 18:36:32

0

你必须确保没有使用需要使用Win32的DLL C运行时也是如此,否则你回到原点。如果其中一个Win32 DLL依赖于C运行时,静态编译您的DLL并不重要。

我可以看到这个工作的唯一方法是静态链接所有您的依赖DLL(如果这是可行的)到您的DLL。这当然意味着您必须重新编译才能利用任何DLL更新。

5

您可能比您想象的更依赖于CRT。它将线程本地存储等资源压缩,全局类初始化程序由main()之前的CRT运行。

正如有人所说,考虑使用静态CRT进行链接,如果您真的不想要,可以像其他人说的那样使用/ NODEFAULTLIB和/ ENTRY。

哦,而不是重写memcpy,考虑使用它的超快速compiler intrinsic。您可以使用/ Oi打开内部函数。

+0

我只使用memcpy作为示例。 – 2009-08-14 18:37:36

+1

就像我一样。有许多编译器内在函数。 – 2009-08-14 18:39:18

+0

它是一个好主意,但是他们是否记录了编译器的内在函数不依赖于它们自己的C运行时的存在? 我假设我可以检查编译器的输出是否可以,但是这比我想象的更多的工作... – 2009-08-14 18:46:35

4

/NODEFAULTLIB链接器标志实际上并不是正确的标志。它会忽略所有默认库,包括其他像uuid.lib

想要的是/Zl编译器选项,“省略.OBJ中的默认库名称”。

4

为 “调试” 模式试试这个:

  1. 转到项目\ [项目]属性...
  2. 打开配置属性
  3. 打开C/C++
  4. 打开代码生成
  5. 对于运行时库选择多线程调试(/ MTD)代替多线程调试DLL(/ MDd)

对于“释放”模式,除了在最后一步选择多线程(/ MT)之外,执行相同的步骤。

这会导致程序中使用的任何C运行时函数都静态链接到您的二进制文件。

+0

那个为我工作。我不想将依赖关系移除到MSVCRT,而是以某种方式“限制”可能导致“缺失依赖性”错误的其他依赖项。 – Matthieu 2016-06-27 13:12:51

相关问题