标签 - Windows编程

? Windows编程 ?    2020-04-20 12:24:43    2207    0    0

什么是 API?

所谓API就是Application Programming Interface的缩写,其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令。

在 Windows 中,系统 API 是以函数调用的方式提供的,API 函数都是包含在系统 DLL 中的导出函数,DLL 文件不能直接执行,它们通常由 exe 在执行时装入,其内含有一些资源以及可执行代码等,系统 DLL 中就含有了 API 函数的执行代码。

直接调用 API 编程又称之为 SDK 编程。SDK 即 software develop kit(软件开发工具包)的缩写,它包含了进行 Windows 软件开发的文档和 API 函数的输入库、头文件。早期 SDK 是一个单独发放的包,现在一些开发环境已经包含了它。

API 和 SDK 是开发 Windows 应用程序所必需的东西,所以其他编程框架和类库都是建立在它们之上的。像 MFC 类库就是对 API 的封装,所以 SDK 编程相对比较灵活。SDK 还有一个优点就是其编写的程序体积会比用类库的小得多。

调用 DLL 中的 API 函数

那具体怎么调用 DLL 中的 API 函数呢?

在SDK中API函数的申明是包含在头文件和导入库中的,所以在程序中我们必须要有API函数的头文件(.h)和其导入库(.LIB),可以分别用#include#pragma comment语句加载到程序中。

具体步骤如下:

  1. 包含要调用函数的头文件,比如在文件开头使用#include<Windows.h>,这里的Windows.h就是我们要包含的头文件。
  2. 连接到指定的导入库文件(.LIB)。一般情况下 IDE 默认已经连接了常用的导入库文件,所以这一步不用我们完成。在没有默认连接的情况下,我们可以在文件开头使用#pragma comment(lib, "ws2_32"),其中ws2_32就是导入库的名称。
  3. 调用要使用的 API 函数。

一个弹出对话框的小程序

  1. #include <iostream>
  2. #include <Windows.h>
  3. #include<t
? Windows编程 ?    2020-04-20 10:25:34    642    0    0

title

  1. // 无窗口工程.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #include <iostream>
  4. #include <Windows.h>
  5. #pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
  6. int main()
  7. {
  8. std::cout << "Hello World!\n";
  9. }

主要是通过:

  1. #include <Windows.h>
  2. #pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")

在头文件中加入如下代码,就不会有控制台窗口了,不会像应用程序那样跳出一个很明显的

? Windows编程 ?    2020-04-09 17:15:21    6040    0    0

工具: Visual Studio 2019

0x01 生成 dll

项目类型选:动态链接库(DLL)

title

项目结构:

title

头文件中:

framework.h 不动,编辑 pch.h

pch.h:

  1. // pch.h: 这是预编译标头文件。
  2. // 下方列出的文件仅编译一次,提高了将来生成的生成性能。
  3. // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
  4. // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
  5. // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
  6. #ifndef PCH_H
  7. #define PCH_H
  8. // 添加要在此处预编译的标头
  9. #include "framework.h"
  10. #endif //PCH_H
  11. extern "C"
  12. {
  13. _declspec(dllexport) int myAdd(int n, int m);
  14. _declspec(dllexport) int mySub(int n, int m);
  15. };

源文件中:

dllmain.cpp 不动,编辑 pch.cpp

pch.cpp:

  1. // pch.cpp: 与预编译标头对应的源文件
  2. #include "pch.h"
  3. #include<iostream>
  4. using namespace std;
  5. // 当使用预编译的头时,需要使用此源文件,编译才能成功。
  6. int myAdd(int n, int m)
  7. {
  8. return n+m;
  9. }
  10. int mySub(int n, int m)
  11. {
  12. return n - m;
  13. }

编译生成 dll:

生成编译,因为我是 Debug 模式下编译的,所以生成的 dll 在项目的 Debug 文件夹下:

title

注:如果没有生成 dll,那就说明报错了。虽然看起来是编译成功。此时应该调试开始执行(不调试),查看报错。比如在我的这个情况中:
title
结果发现是我的源文件多加了一个空文件,没有包含pch.h头文件。于是我删去了这个空文件,重新调试开始执行(不调试)就不报错了。重新编译在 Debug 文件夹下生成了 dll。

0x02