C++ 如何在visual studio中强制Windows.h静态链接而不是动态链接?

C++ 如何在visual studio中强制Windows.h静态链接而不是动态链接?,c++,c,visual-studio,linker,static-linking,C++,C,Visual Studio,Linker,Static Linking,如何强制我的链接器静态链接到Windows.h,使Windows库的所有函数都进入我的可执行文件 我希望VirtualAllocEx、OpenProcess等API调用以及其他API调用(如写入另一个进程的内存等)和CreateRemoteThread(基本上是所有通信API调用和内存分配调用)都在我的可执行文件中,因此我不必使用Windows.h,因此基本上我的IAT不包含这些函数,实现这一目标的最佳方式是什么 A我在微软Windows操作系统下的评论中说,动态库具有一些与静态库代码无关的特性

如何强制我的链接器静态链接到Windows.h,使Windows库的所有函数都进入我的可执行文件


我希望VirtualAllocEx、OpenProcess等API调用以及其他API调用(如写入另一个进程的内存等)和CreateRemoteThread(基本上是所有通信API调用和内存分配调用)都在我的可执行文件中,因此我不必使用Windows.h,因此基本上我的IAT不包含这些函数,实现这一目标的最佳方式是什么

A我在微软Windows操作系统下的评论中说,动态库具有一些与静态库代码无关的特性。让我们试着用非常简单的方式来解释:

首先,DLL作为单独的对象独立于当前可执行文件加载,并直接从OS模块加载函数加载,代码内存映射到当前进程内存中,但保留为映射到不同进程中

在加载过程中,加载程序会创建不同的内存区域,这些内存区域对于单个进程来说是唯一的,或者在进程之间共享,或者对于DLL内部函数来说是私有的

共享区域允许创建互斥、信号量和内核所需的任何数据,以仲裁多任务环境和资源共享

相反,静态库仅在当前进程中加载,代码段与用户程序代码段放在一起,数据段以相同的方式添加到当前可执行数据空间

由于这些原因,以及更多原因,您无法将任何系统库函数静态链接到可执行文件


使用CRT库进行静态和动态链接的简单实验。 在打开文件的位置创建主程序:

#include <stdio.h>
extern void DllReadRoutine(FILE *);
int main(int argc, char *argv[])
{
    FILE *fp = fopen("Myfile.txt", "r");
    //Diagnostic omitted to keep it simple
    DllReadRoutine(fp);    //Pass the file pointer to the external DLL function
    fclose(fp);
    return 0;
}
#包括
外部无效DllReadRoutine(文件*);
int main(int argc,char*argv[])
{
FILE*fp=fopen(“Myfile.txt”、“r”);
//为了保持简单,省略了诊断
DllReadRoutine(fp);//将文件指针传递给外部DLL函数
fclose(fp);
返回0;
}
现在创建DLL(我们省略DLL条目):

#包括
作废DllReadRoutine(文件*fp);
int main(int argc,char*argv[])
{
INTC;
而((c=fgetc(pFile))!=EOF)
{
普查尔(c);
}
}
然后第一次静态(在MSVC上使用/MT)和第二次动态(在MSVC上使用/MD)编译链接CRT的两个文件

在第一种情况下,DLL函数将失败,因为到CRT的静态链接创建的本地打开文件表与主可执行文件的本地表不兼容。结果是一场崩溃

在第二种情况下,内部CRT数据(作为“打开的文件”表)是在共享区域中创建的,可执行文件和DLL都可以访问该共享区域。在这种情况下,代码将顺利运行。

您不能

这些东西是操作系统的一部分

操作系统有权限执行您自己的代码没有的操作

此外,操作系统的实现对于该版本的操作系统是正确的

这是一件好事。您不希望静态链接操作系统的API实现


头文件Windows.h只提供允许您调用它们的声明。

我认为您可能误解了静态链接的过程。h头文件包含各种类型活动的声明,例如函数调用。注意,这些声明不是函数本身的二进制实现。请看一下文档。滚动到文档末尾,您将看到如下所示的需求部分:

要求

Minimum supported client Windows XP [desktop apps only] 
Minimum supported server Windows 2000 Server [desktop apps only] 
Target Platform Windows Header shellapi.h 
Library Shell32.lib 
DLL Shell32.dll (version 3.51 or later)

h包括shellapi.h(目标平台Windows标头)。h包含ShellExecuteA(我们在文档中查找的函数)的声明。本节还将介绍包含函数的二进制实现的库,在本例中为Shell32.lib。如果您知道函数声明及其二进制实现的位置,您可以链接它。链接器只是将(函数)名称与链接时可用的(实现)名称相匹配。在Windows上,您应该能够使用lib文件静态链接,或者使用dll文件动态链接。如果静态链接,则将二进制实现从lib文件包含到可执行文件中。如果MS在您使用的函数中修复了一个,则除非重新编译,否则无法获得该修复。如果您动态链接(链接到dll),您的可执行文件将更小,并且包含更多未来的MS更改。

谢谢您的链接,但是我如何强制它静态链接windows.h@πάντα ῥεῖ“我如何强制它静态链接windows.h?”-这毫无意义。“Windows.h”是头文件,不是库。它可能会暴露某个库(或许多不同的库)中的内容,但它本身并不是一个库。@MeryTed您的google有什么问题吗?我添加了另一个链接。@dedecos即使在这种情况下,我们也可以解释crt库依赖于编译器,因为它包含运行编译器库函数(fopen、get、printf等)所必需的基本函数。一些编译器(如MSVC)允许选择如何使用特定的行开关静态或动态链接它们,因此他必须参考编译器文档。更难解释的是,由于技术原因,2的使用会产生差异。也就是说,选择静态链接不允许在同一进程空间中运行的DLL之间共享文件指针。@πάνταῥεῖ 同样,您不能静态链接系统库,因为每个DLL都使用共享部分来跟踪进程间仲裁,并允许内核与用户代码交互,而不受进程间干扰。简单地说,实际情况要复杂得多
Minimum supported client Windows XP [desktop apps only] 
Minimum supported server Windows 2000 Server [desktop apps only] 
Target Platform Windows Header shellapi.h 
Library Shell32.lib 
DLL Shell32.dll (version 3.51 or later)