静态加载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中的,可以直接调用,定义如下:
使用静态加载的方法使用方面还是很方便的,可是在动态加载的时候就不能直接调用头文件的函数了,增加了复杂度,下面会讲到。
/** * Start receiving accelerometer data periodically. * * The period interval must be a multiple of the callbackPeriod specified * in SmiAccelerometerCapabilities. If it is less than the callbackPeriod, it will be * set to the callbackPeriod. If it is not a multiple of the callbackPeriod, it will be * truncated to fit the value. ( (period / callbackPeriod) * callbackPeriod ) * * Only one handler per process is allowed. Successive calls per process will replace the previous handler * function and period. * * @param period [in] callback interval. * @param handler [in] callback function for every period interval. * * @return * SMI_SUCCESS on success * \n SMI_ERROR_INVALID_PARAMETER if the handler input parameter is NULL * \n SMI_ERROR_DEVICE_NOT_FOUND if the device is not present or supported * \n SMI_ERROR_CANNOT_ACTIVATE_SERVER if the sensor server cannot be started */ SMI_API SMI_RESULT SmiAccelerometerRegisterHandler(UINT period, SmiAccelerometerHandler
|
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的方法就完成了。
阅读(5998) | 评论(0) | 转发(0) |