API入门系列之五 -一个正儿八经的SDK程序

C++边缘AI智能体框架Agents-SDK:本地优先的高性能开发指南 在嵌入式与物联网领域,边缘计算正成为降低延迟、保障数据隐私的关键技术。其核心原理在于将计算任务从云端迁移至网络边缘的设备端执行,从而减少网络传输开销,实现实时响应。这一技术价值在工业自动化、智能终端等对时延和可靠性要求极高的场景中尤为突出。随着大语言模型(LLM)能力的普及,如何在资源受限的边缘设备上高效部署和运行AI智能体,成为工程实践的新挑战。本文聚焦的Agents-SDK,正是一个采用现代C++20标准构建的原生框架,它通过模块化设计、多模型供应商支持及Bazel构建系统,为开发者提供了在边缘侧开发高 阅读详情

原创文章,转载请注明作者及出处。

首发

http://blog.youkuaiyun.com/beyondcode

http://www.cnblogs.com/beyond-code/

http://hi.baidu.com/beyondcode

 

SDK编程群号:81543028 欢迎加入

上一篇,讲了一个简单的SDK程序的多种版本的编写,弹出了一个窗口,显示了我们计算1到10的结果,计算的程序不是重点,重点在于,一:让大家认识到Unicode版本的程序和ASCII版本的程序在编程方面的区别,以及怎么样编写出通用代码的程序。二:怎么样运用API或者c++库函数格式化非字符数据到一个字符串中显示出来。

不过,那个相当简单的程序,还算不上是一个正儿八经的SDK程序,也就是说还不是一个纯爷们儿,因为我们并亲自完成一个SDK程序的经典步骤。而是调用了一个MessageBox API函数,这个函数虽然使用简单,但是在它的内部,那可是相当复杂啊~~~。怎么个复杂法,具体的我不知道,但是我知道的是一个SDK程序的经典步骤它是都用到了的,什么是编写SDK程序的经典步骤呢?新手朋友们听好了哦,现在我就告诉你。

第一步:注册窗口类

第二步:创建窗口

第三步:消息循环

第四步:编写窗口消息处理函数

上面我所说的,听起来都比较专业,下面我就解释一下,什么是注册窗口类呢?注册窗口类就是使用一个 窗口类结构体(WNDCLASSEX) 来描述一类窗口,这类窗口具有相同的属性,也就是你在结构体WNDCLASSEX中指定的那些值。只要是用这个窗口类创建的窗口都具有这些特性。至于WNDCLASS能描述哪些特性,下面会具体讲,这里你只要了解是用一个名叫WNDCLASSEX的结构体来描述一个窗口的类别。

创建窗口应该比较好理解吧,就是创建一个具体的窗口,好像是一句废话嘛。也就是说这个窗口是根据一个窗口类而创建的,不是凭空而造的。意思是你要创建一个窗口,那么必须要有一个已经注册的窗口类。

对于前两步,我打一个比方,就好比你要造一辆车,那们第一步首先是干什么? 当然是设计图纸啦,图纸上就有说明这种车有哪些特性。然后第二步才是根据这个图纸来创建一个具体的看得见的车。所以我上面说的注册窗口类就好比设计窗口的图纸,然后就是根据这个窗口的图纸来创建一个具体的窗口。都说成这样了,应该明了了吧~~

至于消息循环,就是创建的窗口随时都有可能发生很多事情,那么发生的这些事情怎么通知你呢?比如窗口最小化了,窗口大小改变了,怎么通知你呢?  其实就就是通过消息循环不断的取得窗口所发生的事情,然后以消息的形式发送给我们后面要介绍的窗口消息处理函数。

消息处理函数呢就是我们程序员负责编写代码对具体的消息进行具体的处理,当然你也可以不处理,交给系统的默认处理函数来处理。

对于这两步,我也打一个比方。消息循环就好比汽车的一个总传感器,它源源不断的将汽车内部所发生的事情以消息的形式通过仪表板传达给开车的人,开车的人根据具体的事情而采取具体的操作,当然你也可以不操作,无动于衷,对于windows消息来说,不操作倒没有什么,而对于开车的人来说,不操作的后果就不好说了。 在这里,这个总传感器就相当于SDK程序的消息循环,不断的发送消息,而开车的人就相当于窗口消息处理函数,负责处理各种消息。明白了吧,还不明白的话就看看下面的具体的程序吧,也需还有最后一丝希望可以让你恍然大悟。

讲了正儿八经的SDK程序的经典步骤后,我们进入正式的代码阶段,通过代码结合上面所讲理论进一步巩固知识。我讲逐步讲解并逐步编写一个自己注册窗口类,创建窗口,带消息循环,并自己编写消息处理过程的程序。

首先给出程序框架

/* BY beyondcode */

#include <windows.h>

#include <tchar.h>

LRESULT CALLBACK WinMessageProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );

int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )

{

return 0;

}

第一个函数声明,返回类型为LRESULT,本质经查看是long,然后函数调用约定CALLBACK和WINAPI是一样的,都是__stdcall,说明函数调用相关的约定,不必深究。至于为什么用CALLBACK是为了意思显而易见,表示是回调函数,什么是回调函数?也就是系统负责调用的,不必你亲自调用的函数,所以你在你的程序里是看不到调用WinMessageProc这个函数的代码的,你只负责编写它的代码,至于调用,系统会在有消息的时候自动调用它。WinMessageProc的参数类型和个数是规定好了的,不然系统怎么知道怎么掉用,所以不能更改。

再解释一下这四个参数吧,第一个参数是一个窗口的句柄,也就是告诉你,是哪个窗口的消息,第二个参数是消息的类型,告诉你是什么消息,第三个和第四个参数是这个消息所带的一些额外的但是必须的数据。你在窗口消息处理函数中只使用他们就可以了,他们的值都是系统传递进来的。你只是根据他们来判断是哪个窗口的什么消息,并且获取该消息的额外参数信息。

有了程序框架,我们来第一步,注册一个窗口类

   //注册一个名叫MyWindowClass的窗口类

WNDCLASSEX wc;

wc.cbSize = sizeof( wc );

wc.style = CS_VREDRAW | CS_HREDRAW;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

wc.hCursor = LoadCursor( NULL, IDC_ARROW );

wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );

wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );

wc.hInstance = hInstance;

wc.lpfnWndProc = WinMessageProc;

wc.lpszMenuName = NULL;

wc.lpszClassName = _T("MyWindowClass");

if( !RegisterClassEx( &wc ) )

{

MessageBox( NULL, _T("注册窗口类出错"), _T("出错"), MB_OK );

return 0;

}

上面的WNDCLASS的各个成员值我就不一一介绍是什么含义,MSDN上面讲的非常清楚,我只讲一两个比较重点的,第一个lpszClassName这个成员,我们给它指定的是_T("MyWindowClass")这个值,这是指定这个窗口类的名字是什么,因为下面的创建窗口会用到这个名字。

lpfnWndProc这个成员是WinMessageProc这个函数,这是指定这个窗口类所创建的窗口的消息处理函数是哪一个,我们这里指定的是WinMessageProc。其他的参数我就不啰嗦了,各位不懂的MSDN一下或者在群里来交流一下。

指定了这个窗口类有哪些特性后就完了?当然没有,没有注册怎么使用啊,所以还需要注册,注册调用RegisterClassEx这个API函数,将刚才的WNDCLASS变量的地址传给它就可以进行注册了,如果注册失败,返回值为零,成功的话返回值为非零。

注册了窗口类,我们来第二步,创建一个窗口。代码如下:

// 根据上面注册的一个名叫MyWindowClass 的窗口类创建窗口

HWND newWind = CreateWindowEx( 0L, _T("MyWindowClass"), _T("beyondcode"), WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, NULL, NULL, hInstance, NULL );

if( NULL==newWind )

{

MessageBox( NULL, _T("创建窗口出错"), _T("出错"), MB_OK );

return 0;

}

ShowWindow( newWind, nShowCmd );

UpdateWindow( newWind );

可见,创建窗口用CreateWindowEx这个API函数,它的第一个参数是扩展样式,我们这里不设置扩展样式,所以传递0L,第二个参数就是窗口类的名字,我们这里指定我们上面已经注册了的那个名叫MyWindowClass的窗口类,第三个参数是窗口的标题,随便设置,第四个参数是窗口的样式,我们这里设置的是WS_OVERLAPPEDWINDOW,一般主窗口都用这个样式,就是有最大化,最小化框,有标题栏,有系统菜单。。具体的可以参见MSDN,第五个,六个,七个,八个参数分别指定窗口的初始坐标和长宽,第九个参数指定父窗口是哪个,这里没有父窗口,所以传递NULL,第十个参数指定菜单的句柄,我们这里不设置菜单,所以传递NULL,第十一个是应用程序句柄,用WinMain传递进来的那个hInstance参数,第十二个参数表示额外数据,不设置,所以为NULL。

这个API函数有点复杂,不过用熟悉了也就不觉得了。这样我们就创建了一个窗口,返回值是一个窗口的句柄,如果是NULL的话,说明创建窗口失败了,如果不是NULL的话,说明成功了。

光创建成功了还不行,如果你不显示和更新它,你还是看不到它,所以需要调用2个API函数,ShowWindow和UpdateWindow,参数就是刚才创建成功的那个窗口的句柄,至于ShowWindow的第二个参数是指显示的类型,是最大化显示呢还是最小化显示呢,不过在程序中第一次调用ShowWindow必须使用WinMain所传递进来的参数的第四个参数的值。这是MSDN上说的~

窗口创建成功了,下面一步是消息循环了,消息循环说起来复杂,其实代码挺简单的,而且基本格式固定,如下:

//消息循环

MSG msg;

while( GetMessage( &msg, NULL, 0, 0 ) )

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

看到了吗? 一直在一个循环里面,一直调用GetMessage,只要GetMessage所取得的消息不是WM_QUIT的话,那么GetMessage的返回值就不是0,那么循环就一直进行。在循环内部,将GetMessage取得的消息传递给TranslateMessage和DispatchMessage两个API函数进行处理.其中DispatchMessage就是将消息发送给了对应的窗口的窗口消息处理函数进行处理。至于TranslateMessage呢,则进行一些消息的转换,可以先不深究。

最后就是编写窗口消息处理函数的代码了,你需要处理那些消息,那么你就编写处理那些消息的代码,对于你不处理的消息,则统统交给一个叫DefWindowProc的API函数进行默认的处理。

LRESULT CALLBACK WinMessageProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )

{

switch ( msg )

{

case WM_DESTROY:

{

PostQuitMessage( 0 );

break;

}

default:

return DefWindowProc( hwnd, msg, wParam, lParam );

}

return 0;

}

这里我们只处理了WM_DESTROY这个消息,这个消息是在窗口被销毁的时候发送给窗口消息处理函数的,在窗口处理函数中,我们判断这个消息是不是WM_DESTROY,如果是,就调用PostQuitMessage这个API函数,如果是其他消息,我们就不管,将参数全部传递给DefWindowProc这个函数进行处理。

而PostQuitMessage这个API函数的功能就是发送一个WM_QUIT的消息。而我们前面说到过, 在消息循环中GetMessage一旦取得WM_QUIT这个消息,就返回值为0,那么消息循环也就结束了,进而整个程序也就结束了,如果在这里我们处理WM_DESTORY函数,但是不调用PostQuitMessage,那么结果会怎样呢,读者朋友们思考一下~~

好了,到这里,这个什么功能也没有的SDK程序也就完了,它只显示一个带有标题栏的可最大化,最小化的窗口,除了能够关闭它,你几乎不能进行其他任何操作,因为我们除了处理窗口销毁这个消息,其他任何消息我们都没处理。

这篇文章中的源代码在VS2008,windows 7平台下编写并完成编译运行,我会将源代码上传到群空间或其他地方,以方便新手朋友们对比学习~ 

 

Android设备完整性检测:Play Integrity API原理与实战应用 设备完整性验证是移动应用安全领域的核心技术,它通过评估设备硬件、软件及运行环境的可信状态,为应用提供安全准入依据。其核心原理在于构建多层次信任链,从系统底层到应用层进行动态检测,确保设备未被恶意篡改。这项技术的价值在于有效对抗Root、Bootloader解锁、应用重打包等安全威胁,保障金融支付、版权保护、游戏反作弊等高敏感场景的业务安全。在实际应用中,开发者常借助Play Integrity API等标准化方案进行设备状态评估,并结合自定义检测逻辑形成分层防御策略。本文聚焦Android平台的设备完整性检 阅读详情

相关推荐

SDK01- 入门概念

sdk

https://www.yuque.com/onlyxiu-123com 2156

SDK 入门

SDK入门

qq_61553520的博客 4492

SDK编程入门经典,己经够详细了吧

1.实例(instance): 这是C++的内容,“类”相当于结构体的数据类型,用“类”这 种类型去定义一个变量(如果是指针,则假定已经得到了空间),这个变量就是 那个“类”的“实例”。它和C语言中的变量是一回事,不过只有用“类”定义的 变量才称为“实例”。 2.句柄(handle):这是C语言的内容,和文件句柄一样,它实际上是一个整数,用来 标识是哪一个实例,也就是实例的标识符。通过句柄可以操作这个实例。 3.回调(CALLBACK):这其实是C语言中的函数指针,函数指针一般在大项目搭框架时 常常使用。也就是你设计好要得到什么,把接口定义好,具体怎么实现完全交给 别人,别人只要把函数名传给你就OK。这个函数名就是地址,不过取这种地址的 指针在定义上与普通指针有些不同。小雅在《C语言教程》的“函数指针”中有详 细解说和例子。

SDK编程

以上内容是我在学习SDK时的收获,以后也会不断补充相应的内容,当然很多我没有写到,因为知识永远是来用的,学的多用不上也没有用。

qq_45844442的博客 623

windows SDK API教程 API实例解析

windows API教程 用API函数控制光驱的开关 采用API实现的文件拖放 创建和删除快捷方式 建立文件关联 模拟一次鼠标事件 闪烁的标题栏 实现平面工具栏 使窗体右上角的X按钮失效 使用超链接和发送电子邮件Email 使用历史文件记录 任务栏右下角托盘区图标 在菜单中加入图标 自动更换墙纸的小程序

AGV避坑指南:海康控制系统与Modbus设备对接的那些‘坑’

本文深入解析海康AGV控制系统与Modbus设备对接中的常见问题及解决方案,涵盖通信协议对接、信号干扰、硬件层问题和软件优化策略。通过真实案例和实用技巧,帮助工程师规避典型陷阱,提升系统稳定性和效率。

l3m4n的博客 741

Windows API入门系列之五 -一个正儿八经的SDK程序

上一篇,讲了一个简单的SDK程序的多种版本的编写,弹出了一个窗口,显示了我们计算1到10的结果,计算的程序不是重点,重点在于,一:让大家认识到Unicode版本的程序和ASCII版本的程序在编程方面的区别,以及怎么样编写出通用代码的程序。二:怎么样运用API或者c++库函数格式化非字符数据到一个字符串中显示出来。 不过,那个相当简单的程序,还算不上是一个正儿八经的SDK程序,也就是说还不是一

Qsir的专栏 3242

VSCode配置ClangFormat:让C++大括号乖乖不换行(附常见样式对比)

本文详细介绍了如何在VSCode中配置ClangFormat,实现C++代码大括号不换行的格式化风格。通过对比Attach、Allman等主流大括号样式,并提供从快速设置到项目级配置的完整指南,帮助开发者打造统一、高效的代码格式化工作流,提升团队协作效率。

weixin_28835551的博客 216

(转)API入门系列之五 -一个正儿八经的SDK程序

原 API入门系列之五 -一个正儿八经的SDK程序 2009年03月26日 23:51:00 阅读数:5090 出处(https://blog.youkuaiyun.com/beyondcode/article/details/4028236)。 首发 http://blog.youkuaiyun.com/beyondcode http://www.cnblogs.com/beyond-code/ htt...

moshumu1的博客 255

数学建模之0—1规划(Python)

目录 1、概述 (1)知识框架 (2)线性整数规划模型 (3)分支定界法 2、案例 (1)案例1​ (2)案例2 3、遗传算法—sko-GA包实现 (1)代码 (2)结果 4、PuLp实现 (1)代码 (2)结果 5、致谢 1、概述 (1)知识框架 (2)线性整数规划模型 (3)分支定界法 2、案例 (1)案例1 (2)案例2 3、遗传算法—sko-GA包...

weixin_46039719的博客 4112

Cursor使用教程:用 Cursor 创建第一个 Java 项目

Cursor是一款基于VS Code的AI编程编辑器,专为开发者设计。安装前需确保JDK 8+、Maven 3.8+等环境配置,支持Windows系统。编辑器提供中文界面选项,可通过扩展市场安装语言包。创建Java项目支持手动和AI提示词两种方式:手动需创建目录结构并编写代码;AI方式则通过自然语言描述快速生成项目框架和代码。标准Java项目包含src/main/java主代码目录、src/test/java测试目录及pom.xml等配置文件。Maven项目中,pom.xml是核心配置文件,管理项目依赖与构

博客 3548

Windows API入门:5:正式SDK程序

编写一个带有注册窗口类和消息循环的SDK程序

Soda Wang的博客 245

如何利用Dpabi,AFNI,FSL软件计算种子点的功能连接?

fsl_glm 得到的是线性回归系数(beta coefficient),由于在自变量和因变量标准化(均值为 0,标准差为 1)的情况下,简单线性回归的回归系数和皮尔逊相关系数是相同的,因此这是一种间接的方法。(3)上一步得到的 PCC.nii.gz 文件是 Harvard-Oxford 概率模板中的后扣带回,每个体素中的数值(1-100)表示该体素属于 PCC 的概率,反映 PCC 在不同被试中的变异大小,也表示我们对于某个体素属于PCC 的信心。接下来,我们来聊聊功能连接在数据处理里的具体应用。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 7842

嵌入式入门学习方向

电子烟(不多说,这行业技术门槛低,前途堪忧)、充电宝(要求会PD协议,上限太低)、简单消费品(如体重秤等)、简单消费品带无线通信(如蓝牙、4G、WIFI、LORA等)、简单医疗产品(指的是做医疗产品的小公司,其实没什么实力,之所以打医疗的名头出来无非在复杂的消费品上做不过人家,就以产品准确为噱头,真不一定测出来准)、大型医疗公司(后面排名我觉得不分前后,看个人爱好)、大型工控公司、大型高级消费产品公司(如无人机、运动相机、仿apple watch手表之类的产品)、大型电源公司、大型车企。

qq_58662768的博客 2066

【图像去噪(Image Denoising)】关于【图像去噪】专栏的相关说明,包含适配人群、专栏简介、专栏亮点、阅读方法、定价理由、品质承诺、关于更新、去噪概述、文章目录、资料汇总、问题汇总(更新中)

你是否在全网苦寻【图像去噪(ImageDenoising)】的相关资料?你的目标是否是看懂【图像去噪(ImageDenoising)】的相关论文,复现代码,跑出结果,并试图创新?你是否需要发表【图像去噪(ImageDenoising)】的相关论文毕业?你是否需要做【图像去噪(ImageDenoising)】的相关项目,开发软件,研究算法,获得专利或者软著?只要是与【图像去噪(ImageDenoising)】有关的问题,那么请继续往下看。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 2万+

【WRFDA第一期】WRF数据同化概述及资源整理

【WRFDA第一期】WRF数据同化概述及资源整理

WW、forever的博客 1660

免 JAR 依赖、纯 API 调用阿里云短信接口

不用依赖庞大的 jar 就可以发短信

zhangxin09的专栏 1194

GEE初学:谷歌地球引擎GEE入门指南(最新注册全流程)

本教程详细介绍了谷歌地球引擎(GEE)的注册与基础操作流程。主要内容包括:1)非商业账号注册步骤,需提供学术机构凭证和研究目的;2)Google Cloud项目创建与API激活;3)Shapefile文件上传方法及资源ID获取;4)JavaScript脚本编写与地图可视化实现。教程通过代码示例展示了两种多边形显示方式(填充和轮廓模式),并强调了GEE的云端处理优势,包括免费访问40多年卫星数据、无需本地高性能硬件等特点。整个流程从账号注册到首个地图可视化完成约需10-15分钟,适合遥感分析初学者快速入门。

此星光明博客 2143

ZLMediaKit Windows编译快速入门

一、下载源码 前提条件:安装git #国内用户推荐从同步镜像网站gitee下载 git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit #下载cmake编译的包(完整更新文件) cd ZLMediaKit git submodule update --init 二、下载编译器 windows使用cmake来构建项目,需要下载cmake客户端进行创建VS的sln文件 下载地址:cmake-gui 下载完成后解压文件,打开bin目录下

GAQ9527的博客 7812

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

博观人脸算法工作记录

博观人脸算法的使用

qq_58601798的博客 422

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

(一)JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇

JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇(一)前言新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 前言 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用

南老頭 5030

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

上一篇: API入门系列之四 -相当简单的SDK程序
下一篇: API入门系列之六 -自己实现MessageBox
BeYoNDCoDE
博客等级 码龄18年 159粉丝 13原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值