【问题标题】:How to call a C++ method from javascript如何从 javascript 调用 C++ 方法
【发布时间】:2014-07-18 20:52:06
【问题描述】:

我有一个 C++ 方法(该角色正在杀死一些进程)。她需要 2 个参数:a hostname and a port

另一方面,我正在开发一个在 Google Chrome 上运行的网络应用程序(使用 Nodejs 和 AngularJS)。
当我通过浏览器单击一个按钮时,我希望能够通过我的app.js 文件调用 C++ 函数。

我还没有找到如何用 C++“绑定”javascript。

编辑:我认为这个链接可能非常有用 How can I use a C++ library from node.js?

【问题讨论】:

    标签: javascript c++


    【解决方案1】:

    您可以使用Google's V8V8 是 Google 的开源 JavaScript 引擎。 V8 可以运行standalone,也可以是embedded 进入任何C++ 应用程序。

    http://code.google.com/p/v8/

    以下来自 github 的示例演示了将 C++ 类与 Google V8 绑定。 v8_wrap_class.cpp - 作者是尼古拉斯

    /*
     * v8_wrap_class.cpp
     *
     *  Created on: 14/01/2013
     *      Author: nicholas
     *     License: public domain
     */
    
    
    #include <v8.h>
    #include <cstdio>
    #include <string>
    #include <stdexcept>
    #include <memory>
    
    using namespace v8;
    
    /*
    var Simple = function(v)
    {
        this.value = v;
    }
    Simple.prototype.func = function()
    {
        alert(this.value);
    }
    
    var obj = new Simple(4);
    obj.func();
    */
    struct Simple
    {
        double value;
    
        Simple(double v)
         : value(v)
        {
            fprintf(stderr, "Simple::ctor\n");
        }
    
        void func()
        {
            fprintf(stderr, "Simple::func(%f)\n", value);
        }
    
        ~Simple()
        {
            fprintf(stderr, "Simple::dtor\n");
        }
    };
    
    namespace js
    {
    
    /*
     * Retrieve the c++ object pointer from the js object
     */
    template <typename T>
    T* unwrap(const Arguments& args)
    {
        auto self = args.Holder();
        auto wrap = Local<External>::Cast(self->GetInternalField(0));
        return static_cast<T*>(wrap->Value());
    }
    
    /*
     * Construct a new c++ object and wrap it in a js object
     */
    template <typename T, typename... Args>
    Persistent<Object> make_object(Handle<Object> object, Args&&... args)
    {
        auto x = new T(std::forward<Args>(args)...);
        auto obj = Persistent<Object>::New(object);
        obj->SetInternalField(0, External::New(x));
    
        obj.MakeWeak(x, [](Persistent<Value> obj, void* data)
        {
            auto x = static_cast<T*>(data);
            delete x;
    
            obj.Dispose();
            obj.Clear();
        });
    
        return obj;
    }
    
    }
    
    void bind_Simple(Local<Object> global)
    {
        // Name the class in js
        auto name = String::NewSymbol("Simple");
    
        auto tpl = FunctionTemplate::New([&](const Arguments& args) -> Handle<Value>
        {
            if (!args.IsConstructCall())
                return ThrowException(String::New("Cannot call constructor as function"));
    
            HandleScope scope;
    
            // Read and pass constructor arguments
            js::make_object<Simple>(args.This(), args[0]->NumberValue());
    
            return args.This();
        });
    
        tpl->SetClassName(name);
        tpl->InstanceTemplate()->SetInternalFieldCount(1);
    
        auto prototype = tpl->PrototypeTemplate();
    
        // Add object properties to the prototype
        // Methods, Properties, etc.
        prototype->Set(String::New("func"), FunctionTemplate::New([](const Arguments& args) -> Handle<Value>
        {
            auto s = js::unwrap<Simple>(args);
            s->func();
            return {};
        })->GetFunction());
    
        auto constructor = Persistent<Function>::New(tpl->GetFunction());
        global->Set(name, constructor);
    }
    
    int main()
    {
        std::string js_source = R"(
            for(var i = 0; i < 1000; ++i)
            {
                var s = new Simple(4);
                s.value = 5;
                s.func();
            }
        )";
    
        /*
         * This code is mostly uninteresting.
         * Just run the vm with the script provided.
         */
        {
            HandleScope handle_scope;
            Handle<ObjectTemplate> global_template = ObjectTemplate::New();
    
            Persistent<Context> context = Context::New(0, global_template);
            Context::Scope context_scope(context);
    
            auto global = context->Global();
    
            // Wrap the class and bind to the global scope.
            bind_Simple(global);
    
            {
                HandleScope handle_scope;
    
                TryCatch trycatch;
    
                Local<String> source = String::New(js_source.c_str(), js_source.size());
    
                Local<Script> script = Script::Compile(source);
                if (script.IsEmpty())
                {
                    Handle<Value> exception = trycatch.Exception();
                    String::AsciiValue exception_str(exception);
                    throw std::runtime_error(*exception_str);
                }
    
                Local<Value> result = script->Run();
                if (result.IsEmpty())
                {
                    Local<Value> exception = trycatch.Exception();
                    String::AsciiValue exception_str(exception);
                    throw std::runtime_error(*exception_str);
                }
            }
    
            context.Dispose();
            context.Clear();
        }
    
        // Run the GC until there is nothing to reclaim.
        while (!V8::IdleNotification())
            ;
        return 0;
    }
    

    【讨论】:

    • 你将如何使用它从 js 调用 C++ 函数?能举个例子吗?
    • 你必须把整个东西包装成一个节点插件模块。或者,将 C++ 编译为您使用 child_process 运行的小型可执行文件。
    • Brainy,如果您要批量编辑帖子,请确保修复每个帖子中的所有问题。将 [.net] 添加到 [c#] 问题本身并没有帮助,请停止为追求 +2 充斥审查队列。
    【解决方案2】:

    你可以向你的服务器发出一个 ajax 请求,然后在后端调用 c++,也许是在 php.ini 中。 或者这可能有用https://code.google.com/p/tiny-js/

    【讨论】:

      猜你喜欢
      • 2012-04-29
      • 2011-02-01
      • 1970-01-01
      • 2014-03-22
      • 2012-03-06
      • 2012-07-21
      • 1970-01-01
      • 2017-01-17
      • 2011-02-13
      相关资源
      最近更新 更多