浏览器调用本地DLL的方法 您所在的位置:网站首页 动态库调用方法是什么 浏览器调用本地DLL的方法

浏览器调用本地DLL的方法

2024-06-28 13:54| 来源: 网络整理| 查看: 265

要在浏览器中调用本地DLL,常见的方法是使用插件。但是为了安全,现在有的浏览器对插件开发做了限制,不让插件调用外部DLL。比如说Chrome,为了调用外部的DLL,我们只能使用早期的chrome版本。 还有一种方法就是在电脑上安装一个助手程序,浏览器通过HTTP GET请求调用助手程序,助手程序再调用本地DLL,并把调用结果反馈到浏览器中。今天我们就来讨论这种方法。首先助手程序应该是一个WEB服务器,因为只有WEB服务器才能处理浏览器发过来的HTTP GET请求。第二个问题:浏览器怎么发送HTTP GET请求?答案是JavaScript。如果您熟悉JQuery, 那么让浏览器发送HTTP GET请求只需要几行代码:

$.get("http://localhost/",function(data,status){ alert("数据: " + data + "\n状态: " + status); });

如果您不了解JQuery,使用的代码会多一些,如下所示:

//创建XMLHttpRequest对象 var httpRequest try{ // Firefox, Opera 8.0+, Safari httpRequest=new XMLHttpRequest(); } catch (e){ try{// Internet Explorer httpRequest=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ httpRequest=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } } httpRequest.open('GET', 'http://localhost/', true); httpRequest.send();//发送请求 // 获取数据后的处理程序 httpRequest.onreadystatechange = function () { if (httpRequest.readyState == 4 && httpRequest.status == 200) { var str = httpRequest.responseText;//获取到助手程序返回的字符串 alert(str); } };

因为浏览器和助手程序都在同一台电脑上,所以代码中HTTP GET的url就是http://localhost

第三个问题:其实浏览器不仅可以用HTTP GET请求调用助手程序,还可以使用HTTP POST,WebSocket协议。 下面我们来看一看流程图:

流程图很简单。这里最麻烦的地方就在于我们要自己写助手程序,还要安装在每一台电脑上。所以我觉得这个方法比较适合企业内部信息管理系统。助手程序可以用来在网页中操作控制本地的读卡器、打印机、扫描仪、高拍仪、U盾等各种硬件设备。 好,原理部分讲完了,如果您看不太懂,问题也不大,现在我们写几个助手程序的实例,估计写完实例大家就会理解了。每个人会的编程语言是不同的,所以我们写的实例,有JAVA版,PHP版和C++版。 所有实例都提供了源代码,源代码放在github上:https://github.com/Dengxd/SimpleDllHelper DllHelperCpp目录是C++版 DllHelperJava目录是JAVA版 DllHelperPhp目录是PHP版,comATL目录是C++写的com组件,专门给PHP版使用的 TestDll目录是测试用的DLL test.html文件是浏览器使用的网页JavaScript代码 

编写一个测试用的DLL

既然要调用DLL,我们就先写一个测试用的DLL,JAVA和PHP写不了DLL,所以只能用C++ 我的开发环境: Windows 7 旗舰版 SP1 x64 Microsoft Visual Studio Community 2022 (64 位) 主要代码解读: 主要代码就一个函数

__declspec(dllexport) int __stdcall sum(int a, int b) { return a + b; }

这是个求和函数,两个输入参数a和b, 返回a+b 我们的助手程序要调用的就是这个函数 这个项目可以编译出x64和Win32(x86)版本的DLL。Visual Studio自动生成的项目也是奇葩,在主界面上Win32程序叫做x86:

但是到了项目属性配置页面,又变成了Win32:

 

很容易把初学者搞得无所适从。其实在这两个地方x86和Win32是一回事。一般我们都是编译成Release版本的,如果要编译成64位的,就在主界面选择x64,如果要编译成32位的,就在主界面选择x86 如果您不会C++和Microsoft Visual Studio, 不知道怎么编译出DLL, 源码里面提供了编译好的DLL,Release x64版的TestDll.dll在文件夹TestDll\x64\Release中,Debug x64版的TestDll.dll在文件夹TestDll\x64\Debug中, Release Win32版的TestDll.dll在文件夹TestDll\Release中,Debug Win32版的TestDll.dll在文件夹TestDll\Debug中,一般情况下我们会使用Release版本的DLL,如果操作系统是64位的,最好使用x64版,如果操作系统是32位的,只能使用Win32版。如果您手痒很想自己编译的话,可以参考一下这篇文章:https://www.freesion.com/article/6443438938/ 。声明一下,这篇文章不是我写的,只是我搜索到的文章。 

编写JavaScript代码

我们建立一个文件,文件名text.html, 内容如下:

window.onload = function () { document.getElementById("ok").onclick = function () { //创建XMLHttpRequest对象 var httpRequest try{ // Firefox, Opera 8.0+, Safari httpRequest=new XMLHttpRequest(); } catch (e){ try{// Internet Explorer httpRequest=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ httpRequest=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } } httpRequest.open('GET', //'http://localhost/cgi-bin/dllhelpercpp.cgi', 'http://localhost/', true); httpRequest.send();//发送请求 // 获取数据后的处理程序 httpRequest.onreadystatechange = function () { if (httpRequest.readyState == 4 && httpRequest.status == 200) { var str = httpRequest.responseText;//获取到助手程序返回的字符串 alert(str); } }; } }

这代码熟悉JavaScript的同学都能看得懂,我就不解释了。 我们用浏览器打开这个文件,会显示一个按钮“HTTP GET”,点击这个按钮,浏览器就会向助手程序发送HTTP GET请求

编写JAVA版的助手程序

我的开发环境: Windows 7 旗舰版 SP1 x64 IntelliJ IDEA 2021.2.1(Ultimate Edition) java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) 我们使用JNA来调用DLL,关于JNA,网络上文章很多了,大家可以自己去搜一搜,我就不献丑了。大家可以参考一下这篇文章:https://www.freesion.com/article/6443438938/ 前面我们说过,助手程序应该是一个WEB服务器,所以我们就使用spring boot框架,这货自带了一个TOMCAT,省了不少麻烦 主要代码解读:

public interface Mydll extends Library { Mydll instance = Native.load("C:\\TestDll.dll", Mydll.class); int sum(int a,int b); } @RequestMapping("/") @ResponseBody public int dll(HttpServletResponse resp) { int ret=Mydll.instance.sum(1,2); resp.setHeader("Access-Control-Allow-Origin","*"); return ret; }

"C:\\TestDll.dll" 是DLL文件所在的路径,要改成您相应的文件路径 int sum(int a,int b);声明了DLL中对应的函数 int ret=Mydll.instance.sum(1,2); 就是调用DLL中的sum函数 resp.setHeader("Access-Control-Allow-Origin","*"); 这句是为了解决跨域问题的

修改application.yml 把端口改为80 server:   port: 80

特别注意:如果您的WINDOWS是32位的,只能使用Win32版的DLL和32位的JDK。如果您的WINDOWS是64位的,可以使用x64版的DLL和64位的JDK,也可以使用Win32版的DLL和32位的JDK。归纳为一句话: DLL和JDK位数要一致。

现在我们运行这个JAVA程序,然后在浏览器中打开前面写的test.html文件,点击“HTTP GET”按钮:

成功调用DLL

编写PHP版的助手程序 

我的开发环境:

Windows 7 旗舰版 SP1 x64

PHPStudy 8.1.1.3 ,  Nginx 1.15.11, PHP 7.3.4nts

Microsoft Visual Studio Community 2022 (64 位)

PHP调用普通的DLL有两种方法,一种是开发一个PHP扩展,再由PHP扩展调用DLL,第二种是开发一个com组件,php先调用com组件,再由com组件调用DLL。我们采用的是第二种方法。

Php是写不了com组件的,所以我们用C++来写一个com组件。

开发com组件

可以参考这个网页:https://blog.csdn.net/weixin_33507838/article/details/115411281

主要代码解读:

STDMETHODIMP CATLSimpleObject::atlsum(LONG a, LONG b, LONG* c) { // TODO: 在此处添加实现代码 HINSTANCE hinstLib; hinstLib = LoadLibrary(TEXT("c:\\TestDll.dll")); if (hinstLib != NULL) { typedef int(__stdcall* SUM)(int, int); SUM sum; sum = (SUM)GetProcAddress(hinstLib, "sum"); //这是获取dll里面的sum函数 if (NULL != sum) { int ret = sum(a, b); //调用dll的sum函数 * c = ret; //这是设置返回值 } FreeLibrary(hinstLib); } return S_OK; }

"C:\\TestDll.dll" 是DLL文件所在的路径,要改成您相应的文件路径特别注意:TestDll.dll 和 com组件的位数要一致。要么都是x64 ,要么都是Win32(x86)。千万不能一个x64,另一个Win32(x86) Com组件编译出来之后,需要注册,注册需要使用命令行:regsvr32 D:\doc\code\SimpleDllHelper\comATL\x64\Release\comATL.dll 这里D:\doc\code\SimpleDllHelper\comATL\x64\Release\comATL.dll是com组件所在的路径,应该改成您本机上实际的文件路径

开发php代码

总共三行代码:

header('Access-Control-Allow-Origin:*'); //这句是为了解决跨域问题的 $com = new COM("ComATL.ATLSimpleObject") or die("无法调用ComTest"); //初始化com组件 echo $com->atlsum(1, 2); //调用com组件的接口

如果说程序代码是美女们的超短裙,那么我最喜欢的就是PHP了,因为越短越好!还有一点很重要,修改php配置文件,加上一行extension=php_com_dotnet.dll

如果没有这一行, PHP无法调用com组件 最后我们在浏览器中打开前面写的test.html文件,点击“HTTP GET”按钮,将会看到和java助手程序一样的结果

编写C++版的助手程序

我的开发环境: Windows 7 旗舰版 SP1 x64 Microsoft Visual Studio Community 2022 (64 位)

介绍一下我们的思路:先安装一个APACHE HTTPD服务器,然后写一个CGI的程序,由这个CGI程序来调用DLL,最后把CGI程序部署到APACHE HTTPD服务器里面

安装一个APACHE HTTPD服务器

官网下载地址:https://archive.apache.org/dist/httpd/binaries/win32/ 这里面有很多版本,我下载的是这个:httpd-2.2.18-win32-x86-no_ssl.msi

安装的时候,就按照缺省的设置安装,安装完会自动启动apache2.2服务,系统托盘区也会多一个apache的图标:

 

 打开浏览器,输入网址http://localhost/,显示如下:

 出现It works! 就说明已经安装成功。

写一个CGI的程序

由这个CGI程序来调用DLL 主要代码如下:

#include #include int main() { HINSTANCE hinstLib; printf("Access-Control-Allow-Origin:*\n"); printf("Content-type: text/html\n\n"); hinstLib = LoadLibrary(TEXT("c:\\TestDll.dll")); if (hinstLib != NULL) { typedef int(__stdcall* SUM)(int, int); SUM sum; sum = (SUM)GetProcAddress(hinstLib, "sum"); if (NULL != sum) { int ret = sum(1,2); printf("%d", ret); } else { printf("can not find function sum "); } FreeLibrary(hinstLib); } else { printf("load library fail!"); } return 0; }

"C:\\TestDll.dll" 是DLL文件所在的路径,要改成您相应的文件路径 printf("Access-Control-Allow-Origin:*\n");这句是为了解决跨域问题的 printf("Content-type: text/html\n\n");  \n\n这个说明HTTP响应头部结束

printf("%d", ret); 这句是真正在网页上显示的内容

注意事项,因为我们安装的APACHE HTTPD是Win32版本的,所以我们使用的TestDll.dll也必须是Win32(x86)版的,这个CGI程序在编译的时候也要选择Win32(x86)版的。

把CGI程序部署到APACHE HTTPD服务器

我们把编译好的exe文件改名为dllhelpercpp.cgi, 复制到APACHE HTTPD的CGI-BIN目录里面。 打开浏览器,打开网址http://localhost/cgi-bin/dllhelpercpp.cgi,如果出现一个数字3,就说明部署成功了。

测试

现在我们修改test.html文件, 把httpRequest.open('GET',    'http://localhost/',true);  改成httpRequest.open('GET',    'http://localhost/cgi-bin/dllhelpercpp.cgi',true); 用浏览器打开test.html文件,点击“HTTP GET”看看得到的结果是不是和JAVA版本的一样?

CGI程序更进一步的开发

可以参考下面两个网页:https://blog.csdn.net/u010105970/article/details/41278489https://blog.csdn.net/weixin_39652658/article/details/116873261



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有