2.是关于如何加载dll或lib库的。可以看这篇bog   Qt调用dll中的功能函数点击打开链接

****************************************************************************************************************************************************

声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的。并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:

   void HelloWorld();     //函数内部调用Win32 API,功能是弹出一个helloworld提示框   int add(int a,int b);  //实现两个数相加,并返回结果

下面分别通过显示调用和隐式调用两种方法,来模拟Qt如何调用外部dll文件中的功能函数,follow me....

预备知识:

1、如果在没有导入库文件(.lib),而只有头文件(.h)与动态链接库(.dll)时,我们才需要显示调用,如果这三个文件都全的话,我们就可以使用简单方便的隐式调用。

2、通常Windows下程序显示调用dll的步骤分为三步(三个函数):LoadLibrary()、GetProcAdress()、FreeLibrary()

其中,LoadLibrary() 函数用来载入指定的dll文件,加载到调用程序的内存中(DLL没有自己的内存!)

GetProcAddress() 函数检索指定的动态链接库(DLL)中的输出库函数地址,以备调用

FreeLibrary() 释放dll所占空间

1、显示调用

Qt提供了一个 QLibrary 类供显示调用。下面给出一个完整的例子:

  1. #include <QApplication>
  2. #include <QLibrary>
  3. #include <QDebug>
  4. #include <QMessageBox>
  5. #include "dll.h"             //引入头文件
  6. typedef int (*Fun)(int,int); //定义函数指针,以备调用
  7. int main(int argc,char **argv)
  8. {
  9. QApplication app(argc,argv);
  10. QLibrary mylib("myDLL.dll");   //声明所用到的dll文件
  11. int result;
  12. if (mylib.load())              //判断是否正确加载
  13. {
  14. QMessageBox::information(NULL,"OK","DLL load is OK!");
  15. Fun open=(Fun)mylib.resolve("add");    //援引 add() 函数
  16. if (open)                  //是否成功连接上 add() 函数
  17. {
  18. QMessageBox::information(NULL,"OK","Link to Function is OK!");
  19. result=open(5,6);      //这里函数指针调用dll中的 add() 函数
  20. qDebug()<<result;
  21. }
  22. else
  23. QMessageBox::information(NULL,"NO","Linke to Function is not OK!!!!");
  24. }
  25. else
  26. QMessageBox::information(NULL,"NO","DLL is not loaded!");
  27. return 0;  //加载失败则退出28}

myDLL.dll为自定义的dll文件,将其复制到程序的输出目录下就可以调用。显然,显示调用代码书写量巨大,实在不方便。

2、隐式调用

这个时候我们需要三个文件,头文件(.h)、导入库文件(.lib)、动态链接库(.dll),具体步骤如下:

1、首先我们把 .h 与 .lib/.a 文件复制到程序当前目录下,然后再把dll文件复制到程序的输出目录,

2、下面我们在pro文件中,添加 .lib 文件的位置: LIBS+= -L D:/hitempt/api/ -l myDLL

-L 参数指定 .lib/.a 文件的位置

-l  参数指定导入库文件名(不要加扩展名)

另外,导入库文件的路径中,反斜杠用的是向右倾斜的

3、在程序中include头文件(我试验用的dll是用C写的,因此要用 extern "C" { #include "dll.h" } )

下面是隐式调用的实例代码:

  1. #include <QApplication>
  2. #include <QDebug>
  3. extern "C"    //由于是C版的dll文件,在C++中引入其头文件要加extern "C" {},注意
  4. {
  5. #include "dll.h"
  6. }
  7. int main(int argv ,char **argv)
  8. {
  9. QApplication app(argv,argv);
  10. HelloWordl();          //调用Win32 API 弹出helloworld对话框
  11. qDebug()<<add(5,6);    // dll 中我自己写的一个加法函数
  12. return 0;  //完成使命后,直接退出,不让它进入事件循环
  13. }

************************************************************************************************************************************

本来是打算用隐身调用的,但是可能是库的原因,造成无法使用。库是别的公司提供的。so,用的第一种。在后面会贴一些我的code。

jida.h 部分 函数形成如下

  1. BOOL WINAPI JidaDllInstall(BOOL install);
  2. BOOL WINAPI JidaDllInitialize(void);
  3. BOOL WINAPI JidaDllUninitialize(void);
  4. DWORD WINAPI JidaBoardCountW(LPCWSTR pszClass, DWORD dwFlags);
  5. BOOL WINAPI JidaBoardOpenW(LPCWSTR pszClass, DWORD dwNum, DWORD dwFlags,/*@out@*/PHJIDA phJida);
  6. BOOL WINAPI JidaBoardClose(HJIDA hJida);
  7. DWORD WINAPI JidaI2CCount(HJIDA hJida);
  8. DWORD WINAPI JidaI2CType(HJIDA hJida, DWORD dwType);
  9. BOOL WINAPI JidaI2CRead(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);
  10. BOOL WINAPI JidaI2CWrite(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);

在要加载的cpp文件上写上QT,因为dll是window的,里面含有定义的宏DWORD这类,so加上windows.h

  1. #include <windows.h>
  2. #include <QLibrary>
  3. #include "jida.h"

定义指针函数以备调用如:一个add函数。下面第一行为函数,第二行为函数指针。

  1. //int add(int a,int b);
  2. //typedef int (*Fun)(int,int); //定义函数指针,以备调用

下面是我的main.cpp里面的。第一行pHandle是给dll的函数里面的api接口,不同dll接口不同,请忽略,不用在意。

主要是dll的加载。QLibrary jida_lib("jida.dll");

然后引用dll里面的函数。resolve是加载dll里面的函数。括号里面的(JidaDallInstall)是Dell里面的函数名。然后直接调用jida_install即可使用dll里面的JidaDallInstall函数。jida_install是自己自定义的。

  1. //加载dll 函数
  2. FunJidaInstal jida_install=(FunJidaInstal)jida_lib.resolve("JidaDllInstall");    //引用dll里面的JidaDllInstall() 函数

DWORD pHandle = 0; //句柄返回值

  1. //int add(int a,int b);
  2. //typedef int (*Fun)(int,int); //定义函数指针,以备调用
  3. //dll init uninit
  4. typedef BOOL WINAPI (*FunJidaInstal)(BOOL install);     //BOOL WINAPI JidaDllInstall(BOOL install);
  5. typedef BOOL WINAPI (*FunJidaDllInit)(BOOL install);    //BOOL WINAPI JidaDllInitialize(void);
  6. typedef BOOL WINAPI (*FunJidaDllUninit)(BOOL install);  //BOOL WINAPI JidaDllUninitialize(void);
  7. //板子
  8. typedef DWORD WINAPI (*FunJidaBoardCountW)(LPCWSTR,DWORD);             //DWORD WINAPI JidaBoardCountW(LPCWSTR pszClass, DWORD dwFlags); 板子数
  9. typedef BOOL WINAPI (*FunJidaBoardOpenW)(LPCWSTR,DWORD,DWORD,PHJIDA);//打开板子 BOOL WINAPI JidaBoardOpenW(LPCWSTR pszClass, DWORD dwNum, DWORD dwFlags,/*@out@*/PHJIDA phJida);
  10. typedef BOOL WINAPI (*FunJidaBoardClose)(HJIDA hJida);//BOOL WINAPI JidaBoardClose(HJIDA hJida); 板子关闭
  11. //I2C
  12. typedef DWORD WINAPI (*FunJidaI2CCount)(HJIDA);              //DWORD WINAPI JidaI2CCount(HJIDA hJida);
  13. typedef DWORD WINAPI (*FunJidaI2CType)(HJIDA, DWORD ); //DWORD WINAPI JidaI2CType(HJIDA hJida, DWORD dwType);
  14. typedef BOOL WINAPI (*FunJidaI2CRead)(HJIDA, DWORD , BYTE , LPBYTE ,DWORD );//BOOL WINAPI JidaI2CRead(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);
  15. typedef BOOL WINAPI (*FunJidaI2CWrite)(HJIDA, DWORD , BYTE , LPBYTE ,DWORD );//BOOL WINAPI JidaI2CWrite(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);
  16. //声明所用到的dll文件
  17. QLibrary jida_lib("jida.dll");
  18. //加载dll 函数
  19. FunJidaInstal jida_install=(FunJidaInstal)jida_lib.resolve("JidaDllInstall");    //引用dll里面的JidaDllInstall() 函数
  20. FunJidaDllInit jida_dll_init = (FunJidaDllInit)jida_lib.resolve("JidaDllInitialize");
  21. FunJidaDllUninit jida_dll_uninit = (FunJidaDllUninit)jida_lib.resolve("JidaDllUninitialize");
  22. FunJidaBoardCountW jida_board_countw = (FunJidaBoardCountW)jida_lib.resolve("JidaBoardCountW");
  23. FunJidaBoardOpenW jida_board_openw = (FunJidaBoardOpenW)jida_lib.resolve("JidaBoardOpenW");
  24. FunJidaBoardClose jida_board_close = (FunJidaBoardClose)jida_lib.resolve("JidaBoardClose");
  25. FunJidaI2CCount jida_i2c_count = (FunJidaI2CCount)jida_lib.resolve("JidaI2CCount");
  26. FunJidaI2CType jida_i2c_type = (FunJidaI2CType)jida_lib.resolve("JidaI2CType");
  27. FunJidaI2CRead jida_i2c_read = (FunJidaI2CRead)jida_lib.resolve("JidaI2CRead");
  28. FunJidaI2CWrite jida_i2c_write = (FunJidaI2CWrite)jida_lib.resolve("JidaI2CWrite");

进行下简单的判断,dll是否加载成功。.load是加载dll。jida_install是我调用dll里面的dll初始化程序。

等于是调用dll里面的函数,再次看是否加载ok。

  1. if (jida_lib.load()) //判断是否正确加载
  2. {
  3. cout << "qt lib load ok" << endl;
  4. }
  5. else
  6. {
  7. cout << "qt lib load error" << endl;
  8. }
  9. if(jida_install)
  10. {
  11. cout << "dell load ok" <<endl;
  12. }
  13. else
  14. {
  15. cout << "dell load error" <<endl;
  16. }

3.QT中char * 转换为 wchar_t * (LPTSTR)类型

醉了,windows下宏定义了很多char类型 LPTSTR 。今天,直接使用,qt报错,真TM费事。

将“CPU”转化为wcha_t *

  1. QString str = "CPU";
  2. const wchar_t * str_cpu = reinterpret_cast<const wchar_t *>(str.utf16());//char * 转换为 wchar_t * 类型

下面这篇blog很好

QT QString, wchar_t *, TCHAR, CString和其他字符或字符串类型的转化

点击打开链接

    1. //QString to wchar_t *:
    2. const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(fileName.utf16());
    3. //QString to char * given a file name:
    4. QByteArray fileName = QFile::encodeName(aFileName);
    5. const char * encodedName = fileName.constData(); //Valid as long as fileName exists
    6. //QString to char * (general case):
    7. const char * tmp = str.toUtf8().constData();
    8. [/code]
    9. Windows 数据类型: http://msdn.microsoft.com/en-us/library/aa383751.aspx
    10. [code lang="cpp"]
    11. //TCHAR:
    12. #ifdef UNICODE
    13. typedef wchar_t TCHAR;
    14. #else
    15. typedef char TCHAR;
    16. #endif
    17. //LPCTSTR:
    18. #ifdef UNICODE
    19. typedef LPCWSTR LPCTSTR;
    20. #else
    21. typedef LPCSTR LPCTSTR;
    22. #endif
    23. //LPCSTR:
    24. typedef const char * LPCSTR;
    25. //LPCWSTR:
    26. typedef const wchar_t * LPCWSTR;
    27. //LPCWSTR to QString:
    28. QString text(QString::fromUtf16(reinterpret_cast<const unsigned short *>(tmp)));
    29. 另一种解决办法是使用QString::fromWCharArray(),但这个函数可能导致一些尚未解决的wchar_t符号问题。
    30. 最佳的编程风格: 使用L来定义wchar_t宽字符串,比如 L"text" 字义了一个UNICODE字符串"text"。
    31. 今天又看到一个文章,关于字符串之间的转换,比较全面,在此将英文翻译并整理一下。
    32. 原文地址:http://hi.baidu.com/koko200147/blog/item/7e3cad828c9b9bb66d8119cb.html
    33. QString与其他字符类型之间的转换,QString在Qt4中是UNICODE编码的,使用utf16规范。
    34. QString::fromAscii ( const char * str, int size = -1 );
    35. QString::fromLatin1 ( const char * str, int size = -1 );
    36. QString::fromLocal8Bit ( const char * str, int size = -1 );
    37. QString::fromRawData ( const QChar * unicode, int size );
    38. QString::fromStdString ( const std::string & str );
    39. QString::fromStdWString ( const std::wstring & str );
    40. QString::fromUcs4 ( const uint * unicode, int size = -1 );
    41. QString::fromUtf8 ( const char * str, int size = -1 );
    42. QString::fromUtf16 ( const ushort * unicode, int size = -1 );
    43. QString::fromWCharArray ( const wchar_t * string, int size = -1 );
    44. //qstring ->std::string
    45. QString::toStdString () ;
    46. QString::toStdWString ();
    47. //BSTR<->QString,不太了解BSTR是什么,还没用到过,所以不知道对不对
    48. BSTR bstr_str;
    49. QString q_str((QChar*)bstr_str, wcslen(bstr_str));
    50. bstr_str = SysAllocString(q_str.utf16());//remember use SysFreeString on BSTR
    51. //QString<->LPCSTR
    52. QString::toLocal8Bit().constData();
    53. QString::fromLocal8Bit ( const char * str, int size = -1 );
    54. //QString<->LPCWSTR
    55. QString::utf16();
    56. QString::fromUtf16 ( const ushort * unicode, int size = -1 );
    57. //QString<->CString
    58. CString c_str(qstring::utf16());
    59. QString fromUtf16 (LPCTSTR(c_str) );
    60. CString转换为char*
    61. //1.传给未分配内存的const char* (LPCTSTR)指针.
    62. CString cstr(asdd);
    63. const char* ch = (LPCTSTR)cstr;//ch指向的地址和cstr相同。但由于使用const保证ch不会修改,所以安全.
    64. //2.传给未分配内存的指针.
    65. CString cstr = "ASDDSD";
    66. char *ch = cstr.GetBuffer(cstr1.GetLength() + 1);
    67. cstr.ReleaseBuffer();
    68. //修改ch指向的值等于修改cstr里面的值.
    69. //PS:用完ch后,不用delete ch,因为这样会破坏cstr内部空间,容易造成程序崩溃.
    70. //3.第二种用法。把CString 值赋给已分配内存的char *。
    71. CString cstr1 = "ASDDSD";
    72. int strLength = cstr1.GetLength() + 1;
    73. char *pValue = new char[strLength];
    74. strncpy(pValue, cstr1, strLength);
    75. //4.第三种用法.把CString 值赋给已分配内存char[]数组.
    76. CString cstr2 = "ASDDSD";
    77. int strLength1 = cstr1.GetLength() + 1;
    78. char chArray[100];
    79. memset(chArray,0, sizeof(bool) * 100); //将数组的垃圾内容清空.
    80. strncpy(chArray, cstr1, strLength1);
    81. //5.如果上述都不行,使用以下方法
    82. CString origCString("Hello, World!");
    83. wchar_t* wCharString = origCString.GetBuffer(origCString.GetLength()+1);
    84. size_t origsize = wcslen(wCharString) + 1;
    85. size_t convertedChars = 0;
    86. char *CharString;
    87. CharString=new char(origsize);
    88. wcstombs_s(&convertedChars, CharString, origsize, wCharString , _TRUNCATE);
    89. cout << CharString << endl; //成功输出字符串"Hello,World"
    90. 从UTF8编码到GB编码的字符串转换方法:
    91. QString Utf8_To_GB(QString strText)
    92. {
    93. return QString::fromUtf8(strText.toLocal8Bit().data());
    94. }
    95. 从GB编码到UTF8编码的字符串转换方法:
    96. QString GB_To_Utf8(char *strText)
    97. {
    98. return QString::fromLocal8Bit(strText);
    99. }

http://blog.csdn.net/linbounconstraint/article/details/47321103

加载dll、lib库的更多相关文章

  1. Qt中加载Libevent静态库(通过reimp和rs两条语句将lib转为a)

    文章来源:http://blog.sina.com.cn/s/blog_731bf4c90102wnpr.html 本文仅是个人经验总结,若有错误欢迎指教! 最近要做一个跨平台的项目,同时也涉及到网络 ...

  2. 加载dll、lib库(例子的代码很全)

    是关于如何加载dll或lib库的.可以看这篇bog   Qt调用dll中的功能函数点击打开链接 **************************************************** ...

  3. C#调用mingw的so库时无法加载DLL###.so 找不到指定的模块

    使用C#调用mingw的so,报了c# 无法加载DLL“###.so”,: 找不到指定的程序. (异常来自 HRESULT:0x8007007E)开始以为是dll路径问题,使用全路径确认正确后仍然无法 ...

  4. 内存加载DLL

    1.前言 目前很多敏感和重要的DLL(Dynamic-link library) 都没有提供静态版本供编译器进行静态连接(.lib文件),即使提供了静态版本也因为兼容性问题导致无法使用,而只提供DLL ...

  5. lua加载DLL

    .cpp //若没有在项目属性--库文件.依赖文件.包含添加.则添加一下路径 #pragma  comment (lib,"lua5.1.lib") #include " ...

  6. 动态加载dll的实现+远线程注入

    1.在目标进程中申请内存 2.向目标进程内存中写入shellcode(没有特征,编码比较麻烦) 3.创建远线程执行shellcode 之前可以看到shellcode很难编写还要去依赖库,去字符串区等等 ...

  7. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。问题记录

    电脑是win8 64位,安装oracle 11g r2 64位的,谁知道一切装完毕后,打开项目却连不上oracle数据了...首先是pl/sql连不上,装了oracle服务器,应该是不用再装客户端,p ...

  8. C#加载dll 创建类对象

    //加载dll 创建类对象string sqlightAssembly = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "syst ...

  9. Windows x86 x64使用SetThreadContext注入shellcode的方式加载DLL

    一.前言 注入DLL的方式有很多,在R3就有远程线程CreateRemoteThread.SetWindowsHookEx.QueueUserApc.SetThreadContext 在R0可以使用a ...

随机推荐

  1. CMAKE 学习

    http://www.cnblogs.com/coderfenghc/archive/2012/06/16/CMake_ch_01.html

  2. linux 内存管理大图

  3. svn is alread locked

    右键文件夹team →Cleanup就可以了 is not under version control team→ clean 等等更新

  4. 3 - SQL Server 2008 之 使用SQL语句删除约束条件

    基本语法为: ALTER TABLE 表名 DROP CONSTRAINT 约束名1,约束名2…… 如果删除一个约束,不需要逗号后的约束名,如果删除两个及两个以上的约束,必须以逗号隔开. 使用上一节中 ...

  5. Eclipse 每行 80 字符限制的提示线

    有时候希望eclipse和C++编辑器之类有条对齐线 打开 Eclipse, Windows -> Prefereces -> General -> Editors -> Te ...

  6. Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案

    1. 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. ConcurrentModi ...

  7. recursive - simple screenshot but detail principle.

    the code below demonstates the principle of the'recursive-call' that the programing beginner may be ...

  8. Creating a web application.

    About creating web GIS applications As you learn and use ArcGIS for Server, you'll probably reach th ...

  9. An App ID with Identifier 'xxxxxx’ is not available. Please ....

    1.完全关闭Xcode; 2.找到钥匙串,将钥匙串(Keychain)中的对应证书移除: 3.再次打开Xcode,通过 Preferences - Account 4. 删除原先的账号重新登录, 搞定 ...

  10. Delphi动态创建组件,并释放内存

    开发所用delphi版本是xe2,效果图如下: 代码如下: ---------------------------------------------------------------------- ...