美文网首页
在Node.js下编写ObjC及汇编函数与JavaScript交

在Node.js下编写ObjC及汇编函数与JavaScript交

作者: zenny_chen | 来源:发表于2017-12-01 01:57 被阅读0次

    当前稳定版本的Node.js v8.9.1已经引入了实验性的N-API,我们可以通过这组API来写本地C/C++代码以及与之相兼容的其他编程语言的代码与JavaScript层进行交互。本文将介绍我们如何用自己编写的一套包含Objective-C和汇编语言的本地代码与JavaScript进行交互的。在本文中,我们主要介绍在JavaScript层调用本地代码实现的函数。
    在开始之前,我们需要做一些准备工作,包括安装至少版本为8.9.1的Node.js运行时环境,还有node-gyp编译工具,这些可以在这篇博文中找到(看中间段的文字部分)。这篇博文中还包含了如何编译gyp工程的步序,因此这些基本的东西在本文中不详细展开了。下面我们就先列出gyp文件内容:

    {
        "targets": [
        {
            "target_name": "test",
            "sources": [ "native.m", "test.s" ]
        }
      ]
    }
    

    在上述配置文件中,我们可以看到,这里面的目标模块名为test,源文件有Objective-C语言的native.m,以及汇编语言的test.s。
    下面给出最主要的native.m的内容,该源文件列出了暴露给JavaScript端的所有外部函数:

    #include <node_api.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #import <Foundation/Foundation.h>
    
    #define var     __auto_type
    
    extern int ASMSub(int a, int b);
    
    static napi_value MyStringMethod(napi_env env, napi_callback_info info) 
    {
        napi_value world;
        var str = @"Hello, world!".UTF8String;
        var str_len = strlen(str);
        printf("The length is: %zu\n", str_len);
    
        napi_create_string_utf8(env, str, str_len, &world);
        
        return world;
    }
    
    static napi_value MyIntMethod(napi_env env, napi_callback_info info) 
    {
        @autoreleasepool {
            size_t nArgs = 32;
            napi_value inputArgs[32];
            napi_value thisObj;
            
            napi_get_cb_info(env, info, &nArgs, inputArgs, &thisObj, NULL);
    
            napi_value result;
            
            int32_t argValue = 0;
            napi_get_value_int32(env, inputArgs[0], &argValue);
            
            var array = @[@"abc", @"def", @"xyz"];
            
            napi_create_int32(env, ASMSub(100, argValue) + array.count, &result);
          
            return result;
        }
    }
    
    
    napi_value Init(napi_env env, napi_value exports) 
    {
        napi_property_descriptor stringDesc = { "stringMethod", 0, MyStringMethod, 0, 0, 0, napi_default, 0 };
        napi_property_descriptor intDesc = { "intMethod", 0, MyIntMethod, 0, 0, 0, napi_default, 0 };
        napi_define_properties(env, exports, 2, (napi_property_descriptor[]){stringDesc, intDesc});
        
        return exports;
    }
    
    NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
    
    

    当前,node-gyp编译工具链还不是非常成熟,因此Objective-C中还有不少东西无法使用,比如NSNumber类型就不支持,还有NSLog也不支持,这些对于Clang前端而言都能解析得过,但是后端库没有包含,所以我们用node-gyp命令去构建是没问题的,但在运行时就会发生符号找不到的异常。不过我们用用NSString、NSArray这些还是没有问题的。这个源文件中还引入了一个全局函数——ASMSub,这个函数将在下面的汇编文件中实现。

    .text
    .align 4
    .intel_syntax
    
    .globl _ASMSub
    
    
    _ASMSub:
    
        sub edi, esi
        mov eax, edi
        ret
    
    

    以上三个文件都准备好之后,我们就可以在命令行用cd命令进入到此目录中,然后使用node-gyp configure &&node-gyp build命令进行构建。成功的话最后会显示ok
    最后,我们创建一个名为hello.js的JavaScript源文件:

    const test = require('./build/Release/test.node');
    
    const str = test.stringMethod();
    const value = test.intMethod(30);
    
    console.log("String is: " + str);
    console.log("Value is: " + value);
    

    然后我们可以用node hello.js运行来查看结果了。

    相关文章

      网友评论

          本文标题:在Node.js下编写ObjC及汇编函数与JavaScript交

          本文链接:https://www.haomeiwen.com/subject/dicibxtx.html