zoukankan      html  css  js  c++  java
  • QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)good

    方案三:
    时间一分一秒过去,真心着急啊,难不成自己用VC编写?有想法就赶紧行动,找到了古董级别的VS6.0的安装光盘,双击看到阔别七年的安装界面,突然之间有种热泪盈眶的感觉。老朋友啊,当年的编程入门,又记起了当年的大学,当年的图书馆,当年的初恋!
    window.open('http://www.qtcn.org/bbs/attachment/Mon_1405/44_110085_2134fc1bfd2e3f9.png?52');" style="max-700px;max-height:700px;" onload="if(is_ie6&&this.offsetWidth>700)this.width=700;" >

    搞就搞,新建MFC DLL,我的妈呀,VC的命名规则实在让人抓狂!半自动语法提示更是让我有种自杀的冲动!安装了visualAssistX,还是不爽!话说编程也要带着快乐的心情嘛,所以果断放弃!

    怎么办呢?既然QT也是C++,而且有个大名鼎鼎的WPS都是QTMFC混合编程的,所以肯定有方法的,百度谷歌,找到一个qtwinmigrate的东西,在这里万分感谢qtwinmigrate的作者!
    好吧,参考里面的例子,正式开始编写了,咱就先来一个最初级的吧。

    第一步:
    打开qt creator,新建C++ 库项目


    依次下一步,记得在选择需要的模块的时候选择QtGui模块,如果没有选中的话,后面编译通不过,qmfcapp这个类里面用了QtGui模块中的方法。

    第二步:
    将多余的文件删除,_global.h还有其他两个文件删除,因为这是QT新建DLL自带的,我们要写的是可以供其他语言调用的DLL,我这里的例子是只用了一个函数和事件,没有用到界面的东西,所以从qtwinmigrate下面的src文件夹拷贝qmfcapp.hqmfcapp.cpp这两个文件过来即可,如下。



    第三步:
    更改pro文件,改为

    1. TARGET = qtdll
    2. TEMPLATE = lib
    3. CONFIG += dll
    4. SOURCES +=
    5.     qmfcapp.cpp
    6.     main.cpp
    7. HEADERS +=
    8. qmfcapp.h





    main.cpp代码如下

    1. #include "qmfcapp.h"
    2. #include "windows.h"
    3. //windows下DLL函数入口
    4. BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved )
    5. {
    6.     static bool ownApplication = FALSE;
    7.     if ( dwReason == DLL_PROCESS_ATTACH )
    8.         ownApplication = QMfcApp::pluginInstance( hInstance );
    9.     if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
    10.         delete qApp;
    11.     return TRUE;
    12. }
    13. //定义函数回调指针
    14. typedef void (CALLBACK *FunCallBack)(int par);
    15. //定义回调函数
    16. FunCallBack OnEvent=NULL;
    17. //定义回调参数
    18. int par;
    19. //定义C语言类型导出事件函数
    20. extern "C" __declspec(dllexport) void SetFunCallBack(FunCallBack fun,int p)
    21. {
    22.     OnEvent=fun;
    23.     par=p;
    24. }
    25. //定义C语言类型导出函数
    26. extern "C" __declspec(dllexport) int add(int i)
    27. {
    28.     //下面这段代码用来触发事件,如果仅仅是使用add函数的话可以删除.
    29.     if (i==110){
    30.         if (OnEvent){
    31.             //当传入参数为110而且已经定义过回调函数的话,则触发事件.
    32.             OnEvent(120);
    33.         }
    34.     }
    35.     return i*2;
    36. }





    选择release编译,在目录下生成了一个DLL文件,这个文件就可以供VC/C#/VB/JAVA等调用了。

    第四步:编写VCC语言程序测试
    main.c代码如下:

    1. #include <stdio.h>
    2. #include <windows.h>
    3. //定义函数指针
    4. typedef int (*Add)(int);
    5. //定义回调函数指针
    6. typedef void (CALLBACK *FunCallBack)(int);
    7. //定义回调函数处理方法
    8. void CALLBACK HandleEvent(int par)
    9. {
    10. printf("%d ", par);
    11. }
    12. //主函数入口
    13. int main(int argc, char const *argv[])
    14. {
    15. //定义DLL句柄
    16. HINSTANCE hDll = LoadLibrary("qtdll.dll");
    17. if (hDll != NULL)
    18. {
    19. //定义回调函数指针
    20. typedef void (CALLBACK *PFunCallBack)(FunCallBack);
    21. //实例化回调函数指针
    22. PFunCallBack SetFunCallBack=(PFunCallBack)GetProcAddress(hDll,"SetFunCallBack");
    23. //执行回调函数
    24. if (SetFunCallBack){
    25. SetFunCallBack(HandleEvent);
    26. }
    27. //实例化函数指针
    28. Add add = (Add)GetProcAddress(hDll,"add");
    29. //调用DLL中的方法
    30. printf("%d ", add(1));
    31. //调用DLL中的方法并触发事件
    32. printf("%d ", add(110));
    33. FreeLibrary(hDll);
    34. }
    35. return 0;
    36. }





    运行结果如图:


    当传入的参数为110时,会触发事件,返回值120

    第五步:编写C#程序测试

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




    运行结果:


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

    http://www.qtcn.org/bbs/read-htm-tid-56463.html

  • 相关阅读:
    生成15位或者4位随机数 (主要用于微信支付订单号)
    支付签名 MD5Util 排序工具类
    JVM垃圾回收(GC)
    JVM内存区域
    Java实现经典七大经典排序算法
    Java设计模式之装饰者模式
    Java设计模式之单例模式
    提前批笔试一道算法题的Java实现
    Java设计模式之工厂模式
    文件上传和下载
  • 原文地址:https://www.cnblogs.com/findumars/p/6290061.html
Copyright © 2011-2022 走看看