QT編寫DLL給外部程序調用,提供VC/C#/C調用示例(含事件)

最近這陣子,接了個私活,封裝一個開發包俗稱的SDK給客戶調用,查閱了不少人家的SDK,絕大部分用VC編寫,並且VC6.0居多,估計也是爲了兼容大量的XP用戶及IE瀏覽器,XP自帶了VC6.0運行庫,因此無需兼帶其餘DLL便可運行。也發現有些用匯編和C封裝的,那估計是高手才能編寫啊!那怎麼辦呢?眼看一星期的交貨期要到了,因爲本人歷來沒有寫過SDK開發包,內心那個着急啊,趕忙想出了三種處理方案。編程

 

方案一:windows

用本身最熟悉的QT來寫,畢竟QT也是C++的一種嘛,應該能夠和VC通用的。初步實驗,你妹啊,調用不起來,直接廢棄。瀏覽器

 

方案二:app

找VC高手,本身掏錢出來找人寫,客戶是上帝,那可不能耽誤呢!各大羣裏發消息,無奈高手要價過高(一個簡單的socket通訊封裝,協議都有,熟手估計半天,要價8K有點高),絕大部分答話者使用.NET和JAVA語言,這個編寫DLL確定不大適合,你想一想提供個DLL還要客戶安裝個框架,情何以堪!話說衆裏尋他千百度啊,我一個親戚就是專門搞VC開發12年啦,這點程序半天就能夠搞定的,找到以後,時間有限太忙了,沒時間寫,鬱悶!再次放棄!~框架

 

方案三:socket

時間一分一秒過去,真心着急啊,難不成本身用VC編寫?有想法就趕忙行動,找到了古董級別的VS6.0的安裝光盤,雙擊看到闊別七年的安裝界面,忽然之間有種熱淚盈眶的感受。老朋友啊,當年的編程入門,又記起了當年的大學,當年的圖書館,當年的初戀!ide

搞就搞,新建MFC DLL,個人媽呀,VC的命名規則實在讓人抓狂!半自動語法提示更是讓我有種自殺的衝動!安裝了visualAssistX,仍是不爽!話說編程也要帶着快樂的心情嘛,因此果斷放棄!函數

 

怎麼辦呢?既然QT也是C++,並且有個大名鼎鼎的WPS都是QT和MFC混合編程的,因此確定有方法的,百度谷歌,找到一個qtwinmigrate的東西,在這裏萬分感謝qtwinmigrate的做者!測試

好吧,參考裏面的例子,正式開始編寫了,咱就先來一個最初級的吧。ui

 

第一步:

打開qt creator,新建C++ 庫項目

依次下一步,記得在選擇須要的模塊的時候選擇QtGui模塊,若是沒有選中的話,後面編譯通不過,qmfcapp這個類裏面用了QtGui模塊中的方法。

 

第二步:

將多餘的文件刪除,_global.h還有其餘兩個文件刪除,由於這是QT新建DLL自帶的,咱們要寫的是能夠供其餘語言調用的DLL,我這裏的例子是隻用了一個函數和事件,沒有用到界面的東西,因此從qtwinmigrate下面的src文件夾拷貝qmfcapp.h和qmfcapp.cpp這兩個文件過來便可,以下。

 

第三步:

更改pro文件,改成

TARGET = qtdll

TEMPLATE = lib

CONFIG += dll

 

SOURCES += \

    qmfcapp.cpp \

    main.cpp

 

HEADERS +=\

qmfcapp.h

 

main.cpp代碼以下

 1 #include  " qmfcapp.h "
 2 #include  " windows.h "
 3  
 4  // windows下DLL函數入口
 5  BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved )
 6 {
 7      static  bool ownApplication = FALSE;
 8  
 9      if ( dwReason == DLL_PROCESS_ATTACH )
10         ownApplication = QMfcApp::pluginInstance( hInstance );
11      if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
12         delete qApp;
13  
14      return TRUE;
15 }
16  
17  // 定義函數回調指針
18  typedef  void (CALLBACK *FunCallBack)( int par);
19  // 定義回調函數
20  FunCallBack OnEvent=NULL;
21  // 定義回調參數
22  int par;
23  
24  // 定義C語言類型導出事件函數
25  extern  " C " __declspec(dllexport)  void SetFunCallBack(FunCallBack fun, int p)
26 {
27     OnEvent=fun;
28     par=p;
29 }
30  
31  // 定義C語言類型導出函數
32  extern  " C " __declspec(dllexport)  int add( int i)
33 {
34      // 下面這段代碼用來觸發事件,若是僅僅是使用add函數的話能夠刪除.
35       if (i== 110){
36          if (OnEvent){
37              // 當傳入參數爲110並且已經定義過回調函數的話,則觸發事件.
38              OnEvent( 120);
39         }
40     }
41  
42      return i* 2;
43 }
View Code

 

選擇release編譯,在目錄下生成了一個DLL文件,這個文件就能夠供VC/C#/VB/JAVA等調用了。

 

第四步:編寫VC和C語言程序測試

main.c代碼以下:

 1 #include <stdio.h>
 2 #include <windows.h>
 3  
 4  // 定義函數指針
 5  typedef  int (*Add)( int);
 6  // 定義回調函數指針
 7  typedef  void (CALLBACK *FunCallBack)( int);
 8  
 9  // 定義回調函數處理方法
10  void CALLBACK HandleEvent( int par)
11 {
12 printf( " %d\n ", par);
13 }
14  
15  // 主函數入口
16  int main( int argc,  char  const *argv[])
17 {
18  // 定義DLL句柄
19  HINSTANCE hDll = LoadLibrary( " qtdll.dll ");
20  if (hDll != NULL)
21 {
22  // 定義回調函數指針
23  typedef  void (CALLBACK *PFunCallBack)(FunCallBack);
24  
25  // 實例化回調函數指針
26  PFunCallBack SetFunCallBack=(PFunCallBack)GetProcAddress(hDll, " SetFunCallBack ");
27  // 執行回調函數
28  if (SetFunCallBack){
29 SetFunCallBack(HandleEvent);
30 }
31  
32  // 實例化函數指針
33  Add add = (Add)GetProcAddress(hDll, " add ");
34  // 調用DLL中的方法
35  printf( " %d\n ", add( 1));
36  
37  // 調用DLL中的方法並觸發事件
38  printf( " %d\n ", add( 110));
39  
40 FreeLibrary(hDll);
41 }
42  return  0;
43 }
View Code

 

運行結果如圖:

當傳入的參數爲110時,會觸發事件,返回值120。

 

第五步:編寫C#程序測試

 1  using System;
 2  using System.Collections.Generic;
 3  using System.Text;
 4  using System.Runtime.InteropServices;
 5  
 6  namespace qtdllTestNET
 7 {
 8      class Program
 9     {
10          // 聲明DLL中的函數
11          [DllImport( " qtdll.dll ")]
12          public  static  extern  int add( int i);
13          // 聲明DLL中的回調函數,即事件
14          [DllImport( " qtdll.dll ")]
15          public  static  extern  void SetFunCallBack([MarshalAs(UnmanagedType.FunctionPtr)] CallbackFun pCallbackFun);        
16         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
17          public  delegate  void CallbackFun( int i);
18  
19          public  static  void HandleEvent( int i)
20         {
21             Console.WriteLine(i);
22         }
23  
24          static  void Main( string[] args)
25         {
26             CallbackFun HandleEventX = HandleEvent;
27             SetFunCallBack(HandleEventX);            
28             Console.WriteLine(add( 1));
29             Console.WriteLine(add( 110));
30             Console.ReadLine();
31         }
32     }
33 }
View Code

運行結果:

CSDN下載地址:http://download.csdn.net/detail/feiyangqingyun/7327095

相關文章
相關標籤/搜索