windows 用到的API总结和坑(持续更新10/14)

1.VirtualAlloc 函数 (memoryapi.h) 指定位置分配内存

  • 链接

https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc

  • 语法
LPVOID VirtualAlloc(
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flAllocationType,
  DWORD  flProtect
);
  • 参数说明

lpAddress
①要分配的区域的起始地址。如果正在保留内存,则指定的地址将向下舍入到最接近的分配粒度倍数。如果内存已被保留并正在提交,则地址将向下舍入到下一个页面边界。要确定主机上的页面大小和分配粒度,请使用 GetSystemInfo函数。如果此参数为 NULL,则系统确定将区域分配到何处。
②如果此地址位于您尚未通过调用InitializeEnclave 初始化的 enclave 中,则VirtualAlloc 会为该地址处的 enclave 分配一页零。该页面必须先前未提交,并且不会使用英特尔软件防护扩展编程模型的 EEXTEND 指令进行测量。
③如果您初始化的 enclave 中的地址,则分配操作将失败并显示ERROR_INVALID_ADDRESS错误。

dwSize
区域的大小,以字节为单位。如果lpAddress参数为 NULL,则此值向上舍入到下一页边界。否则,分配的页面包括所有包含一个或多个字节的页面,范围从lpAddress到 lpAddress + dwSize。这意味着跨越页面边界的 2 字节范围会导致两个页面都包含在分配的区域中。

flAllocationType
The type of memory allocation. This parameter must contain one of the following values.
内存分配的类型。此参数必须包含以下值之一。

表格1
价值 意义
MEM_COMMIT
0x00001000
为指定的保留内存页面分配内存费用(来自内存的总大小和磁盘上的页面文件)。该函数还保证当调用者稍后最初访问内存时,内容将为零。除非/直到实际访问虚拟地址,否则不会分配实际的物理页面。
为了保存和提交一步到位的网页,打电话 的VirtualAlloc用 MEM_COMMIT | MEM_RESERVE。

试图通过指定提交一个特定地址范围MEM_COMMIT而不 MEM_RESERVE和非NULL lpAddress除非整个范围已经被预留失败。产生的错误代码是ERROR_INVALID_ADDRESS。

尝试提交已提交的页面不会导致函数失败。这意味着您可以提交页面而无需先确定每个页面的当前提交状态。

如果lpAddress指定了飞地内的地址,则flAllocationType必须是MEM_COMMIT。

MEM_RESERVE
0x00002000
保留进程的虚拟地址空间范围,而不在内存或磁盘上的页面文件中分配任何实际物理存储。
您可以在对VirtualAlloc函数的后续调用中提交保留页 。要在一个步骤中保留和提交页面,请使用 MEM_COMMIT调用VirtualAlloc | MEM_RESERVE。

其他内存分配函数,例如malloc和 LocalAlloc,在释放之前不能使用保留范围的内存。

记忆重置
0x00080000
指示由lpAddress和 dwSize指定的内存范围内的数据不再感兴趣。不应从页面文件中读取或写入页面。但是,该内存块稍后将再次使用,因此不应将其取消提交。此值不能与任何其他值一起使用。
使用此值并不能保证使用MEM_RESET操作的范围 将包含零。如果您希望范围包含零,请取消提交内存,然后重新提交。

当您指定MEM_RESET 时, VirtualAlloc函数会忽略flProtect的值 。但是,您仍必须将flProtect设置为有效的保护值,例如PAGE_NOACCESS。

如果使用MEM_RESET并且内存范围映射到文件,VirtualAlloc将返回错误 。共享视图仅在映射到分页文件时才可接受。

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO应该只在之前成功应用MEM_RESET的地址范围上 调用。它表明 调用者对lpAddress和dwSize指定的指定内存范围内的数据感兴趣,并试图逆转MEM_RESET的影响。如果函数成功,则表示指定地址范围内的所有数据都完好无损。如果该函数失败,则地址范围内的至少一些数据已被零替换。
此值不能与任何其他值一起使用。如果MEM_RESET_UNDO叫上这是不是一个地址范围MEM_RESET早些时候,该行为是不确定的。当您指定MEM_RESET 时, VirtualAlloc函数会忽略flProtect的值 。但是,您仍必须将flProtect设置为有效的保护值,例如PAGE_NOACCESS。

在Windows Server 2008 R2,Windows 7中,在Windows Server 2008,Windows Vista中,Windows Server 2003和Windows XP中: 该MEM_RESET_UNDO标志之前,不支持Windows 8和Windows Server 2012中。

该参数还可以指定如下所示的值。

表 2
价值 意义
MEM_LARGE_PAGES
0x20000000
使用大页面支持分配内存。
大小和对齐方式必须是大页面最小值的倍数。要获得此值,请使用 GetLargePageMinimum函数。

如果指定此值,则还必须指定MEM_RESERVE和MEM_COMMIT。

MEM_PHYSICAL
0x00400000
保留可用于映射地址窗口化扩展(AWE) 页面的地址范围 。
此值必须与MEM_RESERVE一起使用,不得与其他值一起使用。

MEM_TOP_DOWN
0x00100000
在可能的最高地址分配内存。这可能比常规分配慢,尤其是在有很多分配时。
MEM_WRITE_WATCH
0x00200000
使系统跟踪写入分配区域中的页面。如果指定此值,则还必须指定MEM_RESERVE。
要检索自分配区域或重置写入跟踪状态以来已写入的页面的地址,请调用 GetWriteWatch函数。要重置写入跟踪状态,请调用GetWriteWatch或 ResetWriteWatch。内存区域的写跟踪功能保持启用状态,直到该区域被释放。

flProtect
要分配的页面区域的内存保护。如果页面正在提交,您可以指定任何一个 内存保护常量。
如果lpAddress指定了飞地内的地址,则flProtect不能是以下任何值:
PAGE_NOACCESS
PAGE_GUARD
PAGE_NOCACHE
PAGE_WRITECOMBINE

  • 返回值

①如果函数成功,则返回值是页面分配区域的基地址。
②如果函数失败,则返回值为NULL。要获取扩展错误信息,请调用GetLastError。

2.错误提示:error LNK2019:无法解析的外部符号 _mysql_close@4;error LNK2019:无法解析的外部符号 _mysql_init@4;error LNK2019:无法解析的外部符号 _mysql_real_connect@32;`

  • 如图所示

在这里插入图片描述

  • 原因

lib文件和dll文件的位数不匹配,缺少32位MySQL的lib文件和dll文件。

  • 解决方法:
    1)步骤一:下载32位的lib文件和dll文件

32/64位MySQL(lib、dll)资源下载地址: http://download.csdn.net/detail/to_baidu/9770882或去官网安装,然后拿头文件和库文件

2)步骤二::拷贝文件到指定目录下
1、将下载的32位的libmysql.lib文件拷贝到MySQl安装目录下的lib文件夹中,或者是项目工程的lib文件夹中。

前提是项目【VC++目录】中的【库目录】中包含了上诉两个lib文件夹的绝对路径。拷贝之前需将原来的libmysql.lib更名;也可以不改变原来的lib文件名称,而将下载了的32位libmysql.lib改名为libmysql32.lib,同时在项目工程的【属性】——【连接器】——【输入】——【附加依赖项】中添加:libmysql32.lib 。

2、将下载的32位libmysql.dll放在工程目录Debug文件夹中或者System32下。
3)步骤三:编译运行即可

3.fatal error C1189: #error : “No Target Architecture” 解决办法

  • 解决方法

然后就可以正常编译了,其实不用这么复杂,直接在b.cpp文件中调整下引用文件的顺序就可以了,如下
#include <Windows.h> //先定义这个文件
#include <a.h> //再定义其他文件

4.gethostname

  • 作用

该函数把本地主机名存放入由name参数指定的缓冲区中。返回的主机名是一个以NULL结束的字符串。主机名的形式取决于Windows Sockets实现-它可能是一个简单的主机名,或者是一个域名。然而,返回的名字必定可以在gethostbyname()和WSAAsyncGetHostByName()中使用。

  • 函数
#include <Winsock2.h>
int PASCAL FAR gethostname(char FAR *name, int namelen);
name: 一个指向将要存放主机名的缓冲区指针。
namelen:缓冲区的长度。

、、、、、、、、、、、、、、、
#include <stdio.h>
#include <unistd.h>
int main()
{
    
    
char name[65];
gethostname(name, sizeof(name));
printf("hostname = %s\n", name);
}

5._BitScanReverse64 求指数幂

inline int64_t  bsr(uint64_t  val)
{
    
    
	int32_t    ret = -1;
	if(0  != val)
	{
    
    
		_BitScanReverse64((unsigned long*)&ret,val);
	}
	return ret;

}

猜你喜欢

转载自blog.csdn.net/weixin_43679037/article/details/120562063