文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何浅析C++动态加载DLL在Windows Mobile下实现

2023-06-17 21:03

关注

如何浅析C++动态加载DLL在Windows Mobile下实现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

静态加载DLL的方法

使用Native C++的开发,一般使用静态加载的方法加载DLL,所谓静态加载就是在程序编译时(Compile Time)直接调用DLL的头文件定义的函数,链接时(Link Time)链接*.lib文件指向DLL的接口,在程序开始运行时(Run Time Start up)加载DLL。

下面讲述使用静态加载DLL的方法,在程序中需要指定加载的*.lib文件,用于链接(Link)。

#pragma comment(lib, "SamsungMobileSDK_1.lib")

使用静态加载的DLL可以直接调用头文件定义的函数,例如:

SmiAccelerometerCapabilities cap;if( SmiAccelerometerGetCapabilities(&cap) != SMI_SUCCESS){    throw;}SmiAccelerometerHandler h = &GetVectorHandler;if(SmiAccelerometerRegisterHandler(1000, h) != SMI_SUCCESS){    throw;}

SmiAccelerometerGetCapabilities()和SmiAccelerometerRegisterHandler()是定义在头文件smiAccelerometer.h中的,可以直接调用,定义如下:

使用静态加载的方法使用方面还是很方便的,可是在动态加载的时候就不能直接调用头文件的函数了,增加了复杂度,下面会讲到。

 SMI_API SMI_RESULT SmiAccelerometerRegisterHandler(UINT period, SmiAccelerometerHandler handler);

C++动态加载DLL的方法

静态加载DLL是比较简单的开发方法,可是有个缺点是程序开始运行的时候就需要加载DLL,如果该DLL不存在,程序就不能启动了。由于Windows Mobile Sensors API库需要自适应具体的设备,也就是说Windows Mobile Sensors API库不能依赖于具体设备的Sensor库,所以不能使用静态加载的方法来引用DLL。下面讲述动态加载DLL的方法。

定义指向函数的指针

动态加载DLL,需要根据头文件来定义指向函数的指针,如下:

typedef UINT (WINAPI * PFN_SmiAccelerometerGetVector)(SmiAccelerometerVector*);  typedef UINT (WINAPI * PFN_SmiAccelerometerGetCapabilities)(SmiAccelerometerCapabilities*);  typedef UINT (WINAPI * PFN_SmiAccelerometerRegisterHandler)(UINT, SmiAccelerometerHandler);typedef UINT (WINAPI * PFN_SmiAccelerometerUnregisterHandler)();  PFN_SmiAccelerometerGetVector pfnSmiAccelerometerGetVector;PFN_SmiAccelerometerGetCapabilities   pfnSmiAccelerometerGetCapabilities;PFN_SmiAccelerometerRegisterHandler   pfnSmiAccelerometerRegisterHandler;PFN_SmiAccelerometerUnregisterHandler pfnSmiAccelerometerUnregisterHandler;

这些指向函数的指针可以对应下面的在smiAccelerometer.h头文件的函数进行定义:

SMI_API SMI_RESULT SmiAccelerometerGetVector(SmiAccelerometerVector *accel);  SMI_API SMI_RESULT SmiAccelerometerGetCapabilities(SmiAccelerometerCapabilities *capabilities);  SMI_API SMI_RESULT SmiAccelerometerRegisterHandler(UINT period, SmiAccelerometerHandler handler);  SMI_API SMI_RESULT SmiAccelerometerUnregisterHandler();

定义是一一对应的。参数入口和返回值都必须完全一致。

初始化指向函数的指针

初始化指向函数的指针的过程也就是动态加载DLL的过程,代码如下:

#define SAMSUNG_SENSOR_DLL  L"SamsungMobilesdk_1.dll"HMODULE hSensorLib = LoadLibrary (SAMSUNG_SENSOR_DLL);if (NULL == hSensorLib){      printf("Unable to load Samsung Sensor DLL\n");      throw std::runtime_error("Unable to load Samsung Sensor DLL");}  pfnSmiAccelerometerGetVector = (PFN_SmiAccelerometerGetVector)      GetProcAddress(hSensorLib, L"SmiAccelerometerGetVector");pfnSmiAccelerometerGetCapabilities = (PFN_SmiAccelerometerGetCapabilities)      GetProcAddress(hSensorLib, L"SmiAccelerometerGetCapabilities");pfnSmiAccelerometerRegisterHandler = (PFN_SmiAccelerometerRegisterHandler)      GetProcAddress(hSensorLib, L"SmiAccelerometerRegisterHandler");pfnSmiAccelerometerUnregisterHandler = (PFN_SmiAccelerometerUnregisterHandler)     GetProcAddress(hSensorLib, L"SmiAccelerometerUnregisterHandler");if (NULL == pfnSmiAccelerometerGetVector){    printf("Unable to find entry point of SmiAccelerometerGetVector\n");      throw std::runtime_error("Unable to find entry point of SmiAccelerometerGetVector");}if (NULL == pfnSmiAccelerometerGetCapabilities){      printf("Unable to find entry point of SmiAccelerometerGetCapabilities\n");      throw std::runtime_error("Unable to find entry point of SmiAccelerometerGetCapabilities");}if (NULL == pfnSmiAccelerometerRegisterHandler){      printf("Unable to find entry point of SmiAccelerometerRegisterHandler\n");      throw std::runtime_error("Unable to find entry point of SmiAccelerometerRegisterHandler");}if (NULL == pfnSmiAccelerometerUnregisterHandler){      printf("Unable to find entry point of SmiAccelerometerUnregisterHandler\n");      throw std::runtime_error("Unable to find entry point of SmiAccelerometerUnregisterHandler");}

LoadLibrary()函数动态加载DLL,GetProcAddress()根据函数的名字 加载函数的入口地址 到指向函数的指针。有点绕口,sorry。如果地址不为空,那么可以根据这个地址调用相应的函数。

调用函数

调用函数的方法和静态加载DLL的方法一样,但是不是直接调用函数的名字,而是使用指向函数的指针来调用,下面的例子可以和静态加载DLL函数调用的例子对比来看。

SmiAccelerometerCapabilities cap;   if( pfnSmiAccelerometerGetCapabilities(&cap) != SMI_SUCCESS)   {      throw;}SmiAccelerometerHandler h = &GetVectorHandler;  if(pfnSmiAccelerometerRegisterHandler(1000, h) != SMI_SUCCESS)  {    throw;}

C++动态加载DLL的方法就完成了。

.NET的世界

下面这段表述不对,请看下面的回复。.NET使用DllImport属性进行P/Invoke不应该叫做动态加载,因为不能卸载,应该叫做按需加载,就是在call这个函数的时候才加载,而不是在程序启动的时候加载。按需加载和静态加载的区别是加载的时间不一样。

{

在.NET里面P/Invoke一个DLL里面的函数全部都是动态加载(这是错的,谢谢Wuya指出,这里应该叫做按需加载,动态加载的方法可以见Wuya到回复)的,使用DllImport属性来定义。如果SmiAccelerometerUnregisterHandler()函数使用在.NET下会定义如下:

[DllImport("SamsungMobileSDK_1.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern uint SmiAccelerometerUnregisterHandler();使用.NET比使用Native C++动态加载相对简单。

}

关于Mobile Sensors API项目

这个项目还是在起步阶段,当前实现了samsung的重力感应器,我把项目host到 Mobile Sensors API - Native unified APIs for Windows Mobile Sensors 了,我会持续改进,把各种sensors的实现到这个项目中。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网行业资讯频道,感谢您对编程网的支持。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯