【问题标题】:Call Function from DLL loaded in front-end javascript (load dll in clientside javascript)从前端 javascript 中加载的 DLL 调用函数(在客户端 javascript 中加载 dll)
【发布时间】:2016-04-19 21:10:11
【问题描述】:

我有一个简单的客户端 javascript 应用程序。我希望它加载一个 DLL 文件(对于 SwipeReader CR100)并从 javascript 代码中调用 DLL 库中的函数。第二种是将监听器添加到 SwipeReader 触发的事件,如 DocumentRead 或 DocumentReadError 并在 javascript 中处理它们。

所以,我有 4 个小问题要解决:

  1. 在javascript中加载DLL(主要是Chrome V8引擎)。
  2. 在 DLL 中调用函数。
  3. 为 DLL 中触发的事件添加侦听器。
  4. 在使用响应对象进行回调时,在 JS 中执行某些操作(警报、console.log 数据)

以前有没有人这样做过,或者这有可能吗?

提前谢谢你, 丹尼尔。

【问题讨论】:

  • 您无法在浏览器中使用 javascript 加载 dll(除非您可以找到一些可以完全禁用所有安全性和沙盒的设置,即使那样我也不确定是否会有所帮助)。但是,您可以在服务器上加载 dll,并让 javascript 与服务器交互(服务器反过来与 dll 交互)。

标签: javascript c# c++ .net dll


【解决方案1】:

我已经做到了。解决方案是使用EdgeJS 作为 NodeJS V8 和 C# CLR 之间的桥梁。 Edge 加载 DLL 并在 V8 和 CLR 之间创建通信通道,消息是 Func<object, Task<object>>function(payload, callback) 形式的函数,在每种语言 VM 之间编组。

我将在下面发布代码示例:
C#

public abstract class NetWebSocket
{
    private Func<object, Task<object>>  SendImpl { get; set; }

    protected NetWebSocket(Func<object, Task<object>> sendImpl)
    {
        this.SendImpl = sendImpl;
    }

    protected abstract Task ReceiveAsync(string message);

    public Func<object, Task<object>> ReceiveImpl
    {
        get
        {
            return async (input) =>
            {
                Console.Out.WriteLine(input);
                await this.ReceiveAsync((string) input);
                return Task.FromResult<object>(null);
            };
        }
    }

    protected async Task SendAsync(string message)
    {
        await this.SendImpl(message);
        return;
    }
}

public class MyNetWebSocketImpl : NetWebSocket
{
    public CHello module;
    private string JSONCodelineDataRepr = "not set";

    public MyNetWebSocketImpl(Func<object, Task<object>> sendImpl) : base(sendImpl)
    {
        // do other stuff after calling the super class constructor  
        module = new CHello();
        module.DocumentReadEvent += this.DocumentReadEventHandler;
        module.DocumentReadErrorEvent += this.DocumentReadErrorEventHandler;
        // uncomment after the websocket communication works
        module.Start();
    }

    protected override async Task ReceiveAsync(string message)
    {
        // not really needed because only the NodeJS Server listens to C# .NET Server messages
        Console.WriteLine(message);
        if (message.Equals("shutdown"))
        {
            module.Close();
        }
        // not necessary (can comment the send function call)
        // if I eventually receive a message, respond with the JSON representation of the Patient ID Card
        await this.SendAsync("I received a message from you, but I'll ignore it and send you the Patient" +
                             " ID Card Data instead.. I'm a fish, so start phishing! PersonData = " +
                             JSONCodelineDataRepr);
        return;
    }

    private async void DocumentReadEventHandler(string args)
    {
        this.JSONCodelineDataRepr = args;
        await this.SendAsync(args);
    }

    private async void DocumentReadErrorEventHandler(string args)
    {
        await this.SendAsync(args);
    }
}

public class Startup
{
    
    public static MyNetWebSocketImpl ws;

    public async Task<object> Invoke(Func<object, Task<object>> sendImpl)
    {
        ws = new MyNetWebSocketImpl(sendImpl);
       
        return ws.ReceiveImpl;
    }
}

Javascript/NodeJS

(function(e,d,g,e){

var edge = require('edge'),
    http = require('http'),
    WebSocketServer = require('ws').Server,
    swipe = edge.func('./dlls/ActiveXCOM.dll');

var server = http.createServer(function(req,res){
    res.writeHead(200, {'Content-Type' : 'text/html'});
    res.end((
        function () { /*
            <!DOCTYPE html>
            <html>
            <head>
            </head>
            <body>
                <div id='jsonOutput'>
                </div>
                <script>
                    var ws = new WebSocket('ws://' + window.document.location.host);
                    
                    ws.onmessage = function (event) {
                        console.log(event.data);
                        var div = document.getElementById('jsonOutput');
                        div.innerHTML = event.data;
                    }

                    ws.onopen = function (event) {
                        // send something to the server
                        ws.send('I am the client from the browser calling you, the NodeJS WebSocketServer!');
                    }

                    ws.onclose = function (event) {
                        alert('websocket closing');
                    }

                    window.onbeforeunload = function myonbeforeUnload() {
                        return "Are you sure?";
                    }

                    window.onunload = function myonunload() {
                        confirm('Are you really sure?');
                        ws.close();
                        return "Are you really sure?";
                    }
                </script>
            </body>
            </html>
        */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]);
});

var wss = new WebSocketServer({server: server});

wss.on('connection', function(ws) {
    var sendImpl = function (message, callback) {
        console.log(message);
        ws.send(message);
        callback();
    };

    var receiveHandler = swipe(sendImpl, true); 

    ws.on('message', function (message) {
        receiveHandler(message);
    });

    ws.on('close', function close(){
        console.log('****************************The client disconnected!');
        receiveHandler('shutdown');
        delete receiveHandler;
    });
});

server.listen(process.env.PORT || 8080);
module.exports = this;
})();

我希望实现是明确的。如果您对它有任何理解困难,请不要犹豫给我写信。

编码愉快!

[不要听反对者的话!]

【讨论】:

    【解决方案2】:

    从 javascript 代码中调用 DLL 库中的函数。

    没有。您不能在 JavaScript 中加载 DLL。

    为什么?

    JavaScript 在浏览器的堆栈中执行。要使任何东西可用,您必须将其与浏览器连接起来,然后使其可访问;工作量太大。

    解决方法

    您可以使用 C# 编写的客户端应用程序连接到 JS websocket,然后传输数据。 WebSocket 可以检查特定的数据块,并按照您想要的方式对其进行处理。

    我已按照我在使用指纹扫描仪的项目中描述的方式使用它。效果很好!如果您添加一点 Crypto,那就更好了!

    【讨论】:

    • 我不希望在客户端安装除 CR100 驱动程序之外的任何应用程序。我已经开发了一个 C# 应用程序,它可以安装在使用 CR100 驱动程序的客户端计算机上,并启动一个 WCF Json REST 服务,可以调用该服务从 SwipeReader 获取数据。我希望调用 REST 服务的 Angular 应用程序使用驱动程序本身(通过 javascript 模块)。首先,我希望它可以在纯 javascript 中工作。一步一步来。我认为这有点像 navigator.getUserMedia 如何启动笔记本电脑网络摄像头并从中捕获视频。
    • 好吧,你不能在 JavaScript 中使用任何 .dll。为什么不让 Angular 应用与 WCF 应用对话?
    • 已经完成了。 Angular 调用该 REST 服务并获取 ID 卡数据。下次我应该更具体一点。“我希望调用 REST 服务的 Angular 应用程序本身(通过 javascript 模块)使用驱动程序(.dll 文件)。”抱歉,Angular 应用程序已经连接到安装在客户端机器上的应用程序,该应用程序使用 webapp 公开 json 休息服务和端点来获取身份证数据。
    • 哦,在这种情况下,我真的很抱歉告诉你,但这是不可能的。 JS 不能使用任何特定于上下文的二进制文件。
    • 没错。正如我所说,JavaScript 和 .dll 之间没有本机接口。我告诉过你,是的,有可能,但按照你说的方式,不可能。 :) 是的,如果你能发布一个样本就太好了!
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 2021-06-06
    • 1970-01-01
    相关资源
    最近更新 更多