JavaScript引擎研究与C++ 互相调用

合集下载

c调用js代码

c调用js代码

c调用js代码以C调用JS代码在Web开发中,我们经常需要在网页中嵌入一些JavaScript代码来实现一些动态效果或交互功能。

而在C语言中,我们也可以通过调用JavaScript代码来实现一些特定的功能。

要实现C调用JS代码,我们可以利用一些现成的库或框架,比如V8引擎、SpiderMonkey等。

这些工具可以帮助我们在C代码中嵌入JS代码,并通过调用相关的函数来执行JS代码。

我们需要在C代码中引入相关的头文件,并初始化JS环境。

然后,我们可以创建一个JS上下文,用来执行JS代码。

在创建JS上下文之后,我们可以加载JS代码,并通过调用相关的函数来执行它。

在C代码中调用JS代码时,我们可以通过传递参数的方式来实现C 和JS之间的数据交互。

比如,我们可以将C语言中的变量传递给JS代码,或者将JS代码中的结果返回给C语言。

下面是一个简单的示例,演示了如何在C代码中调用JS代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <jsapi.h>int main() {// 初始化JS环境JS_Init();// 创建JS上下文JSContext *ctx = JS_NewContext();// 创建全局对象JSObject *global = JS_NewGlobalObject(ctx);// 设置全局对象JS_SetGlobalObject(ctx, global);// 进入执行上下文JSAutoRequest ar(ctx);// 创建一个JS字符串const char *script = "function add(a, b) { return a + b; }";// 编译JS代码JS::CompileOptions options(ctx);JS::RootedScript scriptRoot(ctx);if (!JS::Compile(ctx, options, script, strlen(script),&scriptRoot)) {printf("Failed to compile JS code\n");return 1;}// 执行JS代码JS::RootedValue result(ctx);if (!JS_ExecuteScript(ctx, scriptRoot, &result)) { printf("Failed to execute JS code\n");return 1;}// 解析JS代码的结果JSString *str = JS::ToString(ctx, result);// 将JS字符串转换为C字符串char *res = JS_EncodeStringToUTF8(ctx, str);// 输出结果printf("Result: %s\n", res);// 释放内存JS_free(ctx, res);// 清理JS环境JS_DestroyContext(ctx);JS_ShutDown();return 0;}```在上面的示例中,我们首先初始化了JS环境,并创建了一个JS上下文。

spidermonkey-让你的c程序支持javascript脚本

spidermonkey-让你的c程序支持javascript脚本

SpiderMonkey-让你的C 程序支持JavaScript脚本译序有些网友对为什么D2JSP能运行JavaScript脚本程序感到奇怪,因此我翻译了这篇文章,原文在这里。

这篇教程手把手教你如何利用SpiderMonkey创建一个能执行JavaScript脚本的C++程序,并让JavaScript脚本操纵你的C++程序的内部数据、操作。

从这篇教程可以看到在SpiderMonkey引擎的帮助下,让C++程序支持JavaScript 脚本是一件很容易的事,更棒的是SpiderMonkey也可以在Macintosh和Unix平台使用。

SpiderMonkey是Gecko(Firefox浏览器的内核)的JavaScript脚本引擎,详细文档请看这里。

以下为翻译内容。

------------------------------------------------本教程的目的是教你如何用JavaScript做为脚本语言使你的C++程序自动化。

SpiderMonkeySpiderMonkey是Mozilla项目的一部分,用C语言写成,是负责执行JavaScript脚本的引擎。

另外还有一个叫Rhino 的Java引擎。

SpiderMonkey的最新版本可在这里下载。

它是以源代码形式发布的,因此你必须自己编译它(译注:其实网上有很多编译好的二进制版本,google一下js32.dll就可找到)。

Visual C++用户可以在src目录下找到Workspace项目工程文件来编译,编译结果会产生一个叫'js32.dll'的dll文件。

SpiderMonkey也可以在Macintosh和Unix上使用,想了解如何在这些平台上进行编译请阅读Readme.html。

在C++中执行JavaScript程序步骤1-创建JavaScript runtime(运行时实例)初始化一个JavaScript runtime可用JS_NewRuntime方法,该方法将为runtime分配内存,同时还得指定一个字节数,当内存分配超过这个数字时垃圾收集器会自动运行。

c#后台写javascript前端调用

c#后台写javascript前端调用

c#后台写javascript前端调⽤最近⽐较清闲,就来逛逛控件⽹,发现了⼀个⾮常好的类库,可惜没看到源代码,不过使⽤⽅式和dll类库倒是能下载到,先发来贴这⾥,⽤起来⽐较⽅便针对的情况是c#后台代码写个函数,然后前端代码可以直接调⽤,确实蛮⽅便,增加了前后台的交互。

这种⽅式⽤c#+EasyUI+Ajax.dll可以很⽅便的从c#后台拉送数据EasyUI做HTML展现,Ajax.dll做数据传输的桥梁。

演⽰的DEMO就1个default页⾯:<%@ Page Language="C#" AutoEventWireup="true"Codebehind="Default.aspx.cs" Inherits="DemoAjaxApp._Default" %><%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35"Namespace="System.Web.UI" TagPrefix="asp" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head runat="server"><title>Ajax Demo</title><script language="javascript" type="text/javascript">function CallTest(){var id=document.getElementById('txtClientId').value;Test(id);}function NameLength(obj){var i=0;var newdiv = document.getElementById('EmpData');newdiv.innerHTML = "";if(obj == null){newdiv.innerHTML = "No Employee Found";return;}mytable = document.createElement("table");mytable.cellSpacing = "0px";mytable.style.border = "1px solid #000";mytablebody = document.createElement("tbody");mycurrent_row = document.createElement("tr");for(i=0;i<obj.Rows[0].Columns.length;i++){mycurrent_cell = document.createElement("td");currenttext = document.createTextNode(obj.Rows[0].Columns[i].Name);mycurrent_cell.appendChild(currenttext);mycurrent_cell.style.border ="1px solid #000";mycurrent_row.appendChild(mycurrent_cell);}mytablebody.appendChild(mycurrent_row);for(var j=0;j<obj.RowCount;j++){var objRow = obj.Rows[j];mycurrent_row = document.createElement("tr");for(i=0;i<objRow.Columns.length;i++){mycurrent_cell =document.createElement("td");if(objRow.Columns[i].Value != null)currenttext =document.createTextNode(objRow.Columns[i].Value+ " ");elsecurrenttext =document.createTextNode(" ");mycurrent_cell.appendChild(currenttext);mycurrent_cell.style.border ="1px solid #000";mycurrent_row.appendChild(mycurrent_cell);}mytablebody.appendChild(mycurrent_row);}mytable.appendChild(mytablebody);newdiv.appendChild(mytable);}function Error_Test(obj){alert(obj.ErrMsg);}function CallTest1(){var x = new Array();x[0] = "Mehul";x[1] = "Thakkar";PassArrayObject(x);}function ReturnClassObject(obj){alert();}function Error_PassArrayObject(obj){alert(obj.ErrMsg);}function CallReturnEvenOdd(){var id = document.getElementById('txtNumber').value;var msg = ReturnEvenOdd(id);alert(msg);}function CallTest2(){var x = new Object(); = "Mehul-Thakkar";x.Phone = 25460645;x.Email = "mehult@";x.JoiningDate = "15-09-2010";PassClassObject(x);}function ReturnLength(obj){alert(obj);}function Error_PassClassObject(obj){alert(obj.ErrMsg);}function CallBack_ReturnArray(arrObj){var Total=0;for(var i in arrObj)Total+=parseInt(arrObj[i],10);alert(Total);}function CallBack_ReturnStrArray(arrObj){var str='';for(var i in arrObj)str+=arrObj[i]+"\n";alert(str);}function CallBack_ReturnObject(clsObj){alert(clsObj.Email);}function CallBack_ReturnFArray(arrObj){var Total=0;for(var i in arrObj)Total+=parseFloat(arrObj[i],10);alert(Total);}</script></head><body><form id="form1" runat="server"><asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager><div><div style="border: solid 1px yellow">Enter Emp No Here:<input type="text" id="txtClientId"/><a href="#" onclick="CallTest()">Retrieve Emp</a><div id="EmpData"></div></div><br /><div style="border: solid 1px blue">Pass Array Object:<a href="#" onclick="CallTest1()">Click Here</a><div id="Div1"></div></div><br /><div style="border: solid 1px green">Pass Class Object:<a href="#" onclick="CallTest2()">Click Here</a><div id="Div2"></div></div><br /><div style="border: solid 1px orange">Return Array Object:<a href="#" onclick="ReturnArray()">Click Here</a><div id="Div3"></div></div><br /><div style="border: solid 1px brown">Return String Array Object:<a href="#" onclick="ReturnStrArray()">Click Here</a><div id="Div5"></div></div><br /><div style="border: solid 1px pink">Return Double Array Object:<a href="#" onclick="ReturnFArray()">Click Here</a><div id="Div6"></div></div><br /><div style="border: solid 1px gray">Return Class Object:<a href="#" onclick="ReturnObject()">Click Here</a><div id="Div4"></div></div><br /><div style="border: solid 1px silver">Synchronous Call using AJAX:<input type="text" id="txtNumber"/><a href="#" onclick="CallReturnEvenOdd()">Click Here</a><div id="Div7"></div></div><br /><div style="border: solid 1px red">Access this textbox from Ajax dll<asp:TextBox runat="server" ID="txt"></asp:TextBox><a href="#" onclick="ControlAccess()">Get Error</a></div></div><asp:UpdatePanel runat="server" ID="UP1"><ContentTemplate><asp:TextBox runat="server" ID="txt1"></asp:TextBox><asp:Button runat="server" ID="b1"Text="click here" OnClick="b1_Click"/></ContentTemplate></asp:UpdatePanel></form></body></html>Default.CS⽂件如下:using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;namespace DemoAjaxApp{public class Temp{string _name, _email;int _phone;public string Name { get { return _name; } set { _name = value; } }public int Phone { get { return _phone; } set { _phone = value; } }public string Email { get { return _email; } set { _email = value; } }}public partial class _Default : System.Web.UI.Page{[Ajax.AjaxMethod("Test", "NameLength", null, "Loading...")]public DataTable Test(string Id){System.Data.SqlClient.SqlConnection con =new System.Data.SqlClient.SqlConnection("server=mehul;Database=master;User Id=sa;Password=");System.Data.SqlClient.SqlDataAdapter Adp =new System.Data.SqlClient.SqlDataAdapter("Select * from emp where no=" + Id, con);DataTable dt = new DataTable();try{Adp.Fill(dt);if (dt.Rows.Count > 0)return dt;elsereturn null;}catch (Exception ex){return null;}}[Ajax.AjaxMethod("PassArrayObject","ReturnClassObject", null, "Loading...")]public Temp PassArrayObject(string[] str){Temp t1 = new Temp();foreach (string st in str) += st;return t1;}[Ajax.AjaxMethod("PassClassObject", "ReturnLength", null, "Loading...")] public int PassClassObject(Temp str){return .Length;}[Ajax.AjaxMethod("ControlAccess", false, false, "Loading...")] public void ControlAccess(string str){txt.Text = str;}[Ajax.AjaxMethod(false)]public string ReturnEvenOdd(int i){if (i % 2 == 0)return"Number is Even";elsereturn"Number is Odd";}[Ajax.AjaxMethod(null, true, false, "Loading...")]public int[] ReturnArray(){int[] i ={ 1, 2, 3, 4 };return i;}[Ajax.AjaxMethod]public string[] ReturnStrArray(){string[] str ={ "\\'1\\'", "2", "3", "4" };return str;}[Ajax.AjaxMethod(null, true, false, "Loading...")]public double[] ReturnFArray(){double[] i ={ 1.423, 2.543, 3.765, 4.65 };return i;}[Ajax.AjaxMethod(null, true, false, null)]public Temp ReturnObject(){Temp obj = new Temp(); = "hello";obj.Phone = 420840;obj.Email = "hello@";return obj;}protected void Page_Load(object sender, EventArgs e){Ajax.Utility.GenerateMethodScripts(this);}protected void b1_Click(object sender, EventArgs e){txt1.Text = "hello";}}}简单介绍⼀下吧:/** 使⽤Ajax.AjaxMethod类时,是有5个参数的* 1.第⼀个参数是你想客户端调⽤JS的名称,默认是函数名称* 2.第⼆个参数是JS调⽤成功后回调函数的名称默认命名为Callback_<你的函数名>* 3.第三个参数是JS调⽤后台后出现异常时回调函数,默认名称为Error_<你的函数名称>* 4.第四个参数是在调⽤后台代码等待过程中,显⽰的字符信息,默认是String.Empty* 5.第五个参数为是否时异步调⽤,确认你客户端调⽤js时是否为异步调⽤,默认是true(异步)*/这个也是从⽹站类库说明中翻译出来的,⼤概就这个意思!确实蛮⽅便的,省去了ScriptManager注册⼀⼤堆乱七⼋糟的脚本什么的了。

cef 中js 与c++互相调用案例

cef 中js 与c++互相调用案例

在 CEF(Chromium Embedded Framework)中,可以通过 JavaScript 和 C++ 之间的互相调用来实现浏览器端和应用程序端的交互。

下面是一个基本的示例,演示了如何在 CEF 中实现 JavaScript 和 C++ 之间的互相调用:C++ 调用 JavaScript:假设有一个 C++ 函数需要调用 JavaScript 函数并传递参数,可以使用 CEF 提供的ExecuteJavaScript 方法。

以下是一个简单的示例:// 在 C++ 中调用 JavaScript 函数CefRefPtr<CefBrowser> browser;// 假设已有浏览器对象std::string jsFunction ="myJavaScriptFunction('Hello from C++!')"; browser->GetMainFrame()->ExecuteJavaScript(jsFunction, browser->GetMain Frame()->GetURL(),0);JavaScript 调用 C++:在 JavaScript 中调用 C++ 函数通常需要使用 CEF 的扩展机制。

首先,您需要创建一个 C++ 类并将其注册为扩展,然后您可以通过 JavaScript 调用注册的 C++ 函数。

以下是一个简单的示例:// 在 C++ 中注册函数,使其能够被 JavaScript 调用class MyV8Handler :public CefV8Handler {public:MyV8Handler(){}bool Execute(const CefString& name, CefRefPtr<CefV8Value> object,c onst CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefStrin g& exception)override{if(name =="myCppFunction"){// 在此处执行 C++ 函数的逻辑// ...return true;}return false;}// ...};// 注册扩展CefRefPtr<CefV8Handler> handler =new MyV8Handler(); CefRegisterExtension("v8/cef","function myCppFunction() { native funct ion call }", handler);// 在 JavaScript 中调用注册的 C++ 函数myCppFunction();以上是一个简单的示例,展示了如何在 CEF 中实现 JavaScript 和 C++ 之间的互相调用。

在Javascript中调用CC++【Emscripten】

在Javascript中调用CC++【Emscripten】

在Javascript中调⽤CC++【Emscripten】本⽂介绍Emscripten - ⽤于将C/C++的代码向Javascript转换。

可⽤于如这样⼀个应⽤场景:有⼀份历史代码⽤C/C++实现,开发者需要⽤Js 调⽤其中的代码。

介绍Emscripten之前,本⽂梳理asm.js和WebAssembly的相关知识。

⼀. asm.js虽然名字叫“asm.js”,虽然asm.js也可以直接⽤javascript来编写,但是这样写出来的代码可读性⾮常差。

⽽且asm.js的初衷就是将C/C++程序移植到浏览器上来。

所以通常的做法是使⽤C/C++这样的静态类型和⼿动回收内存的语⾔编写程序,然后使⽤编译器将编写的程序编译为asm.js。

在Wasm出现之前,emscripten将C/C++编译成asm.js,步骤如下:⼆. WebAssembly (WASM)WebAssembly(缩写为Wasm)是⽤于基于堆栈的虚拟机的⼆进制指令格式。

Wasm被设计为编程语⾔的可移植编译⽬标,从⽽可以在Web 上为客户端和服务器应⽤程序进⾏部署。

⽐起asm.js,将源代码编译成wasm调⽤时效率更⾼,⽽且对于源代码的保护更好,也是现在的emscripten默认格式。

注:⽬前主流的浏览器均已在2018年、2019年左右⽀持了assembly等。

⽽ASM.js⽀持所有浏览器运⾏,因为asm.js本质上还是js,将其他语⾔编译成为js,我们将这种js成为asm.js,是与ts类似的东西。

⽽assembly是字节码,直接更加底层,已经不是js了,类似于⼀种flash⼀样的技术了,但是是浏览器内置的,必须由浏览器实现,如果浏览器不⽀持,就不能运⾏,可以预见的是,会有浏览器兼容性问题,另外,底层bug更加难以调试和发现。

google地图早先只能在chrome中使⽤的原因就是,其本⾝使⽤相当部分的naitiv代码,所以google地图才能在web中进⾏渲染。

C++和JavaScript脚本的相互调用

C++和JavaScript脚本的相互调用

C++和JavaScript脚本的相互调⽤脚本调⽤C++相对⽐较容易,使⽤ATL组件只需要抛双接⼝即可,但在exe⾥如何做到呢?本⽂实现了在exe⾥脚本和C++的相互调⽤.在EXE⾥也需要对外抛送⼀个继承⾃IDispatch的接⼝.并需要重载它的所有接⼝。

由于⽔平有限,所以难免有错。

// 头⽂件static const GUID IID_CExternal ={ 0x52fee9af, 0xb3b3, 0x4756, { 0x80, 0x10, 0xfe, 0xa8, 0xf9, 0xfd, 0xd3, 0x3f } };class CExternal:public IDispatch{public:CExternal(HWND h);virtual ~CExternal();ULONG __stdcall AddRef() { return 1; }ULONG __stdcall Release() { return 1; }HRESULT __stdcall QueryInterface(REFIID riid, void FAR* FAR* ppv){if (ppv == NULL)return E_POINTER;*ppv = NULL;if (InlineIsEqualGUID(riid, IID_IUnknown)){*ppv = static_cast<IUnknown *>(this);return S_OK;}if(InlineIsEqualGUID(riid, IID_IDispatch) ){*ppv = static_cast<IDispatch FAR *>(this);return S_OK;}if(InlineIsEqualGUID(riid, IID_CExternal) ){*ppv = static_cast<CExternal *>(this);return S_OK;}return E_NOINTERFACE;}HRESULT __stdcall GetTypeInfoCount(UINT FAR* pctinfo){if (pctinfo == NULL){return E_INVALIDARG;}// there is only one function*pctinfo = 1;return NOERROR;}HRESULT __stdcall GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo FAR* FAR* ppTInfo){if (ppTInfo == NULL)return E_INVALIDARG;*ppTInfo = NULL;if (iTInfo != 0)return DISP_E_BADINDEX;*ppTInfo = m_typeinfo;if (m_typeinfo!=NULL)m_typeinfo->AddRef();return NOERROR;}HRESULT __stdcall GetIDsOfNames(REFIID riid,OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid,DISPID FAR*rgdispid){if(lstrcmpiW(*rgszNames,L"exec")==0){*rgdispid=0;return S_OK;}return E_FAIL;}HRESULT __stdcall Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pdispparams,VARIANT FAR* pvarResult,EXCEPINFO FAR* pexcepinfo,UINT FAR* p {if((DISPATCH_PROPERTYGET&wFlags || DISPATCH_METHOD&wFlags)&& dispidMember==0){CComBSTR sRet;exec(pdispparams, &sRet);if (DISPATCH_PROPERTYGET&wFlags){pvarResult->vt=VT_BSTR;pvarResult->bstrVal=sRet.Detach();}return S_OK;}return E_FAIL;}HRESULT __stdcall exec(DISPPARAMS FAR* pdispparams, BSTR *pbstrValue);private:HWND m_hWnd;LPTYPEINFO m_typeinfo;CString GetVariantStr(VARIANT vVal);};// 实现的⽂件CExternal::CExternal(HWND h){csDisplayStr = "";m_typeinfo =NULL;m_hWnd = h;// Create an exec functionstatic PARAMDATA PARAM_VALUE[]={{OLESTR("fnName"),VT_BSTR},{OLESTR("p1"),VT_BSTR}};static METHODDATA rgmdataCCalc={OLESTR("exec"),PARAM_VALUE,0,0,CC_CDECL,2,DISPATCH_METHOD|DISPATCH_PROPERTYGET,VT_BSTR}; static INTERFACEDATA ifdata={&rgmdataCCalc, 1};HRESULT hres=CreateDispTypeInfo(&ifdata, LOCALE_SYSTEM_DEFAULT, &m_typeinfo);}CString CExternal::GetVariantStr(VARIANT vVal){CString csReVal;switch (vVal.vt){case VT_BOOL:{if (vVal.boolVal == VARIANT_TRUE){return("1");}else{return("0");}break;}case VT_I2:{csReVal.Format("%d",vVal.iVal);return(csReVal);}case VT_I4:{csReVal.Format("%d",vVal.lVal);return(csReVal);}// case VT_R8:// {// //csReVal.Format("%f",vVal.dblVal);// csReVal=vVal.dblVal;// return(csReVal);// }case VT_BSTR:{return(CString(vVal.bstrVal));}}return "";}HRESULT __stdcall CExternal::exec(DISPPARAMS FAR* pdispparams, BSTR *pbstrValue) // 脚本的⼊⼝点{// no argument returnif (pdispparams->cArgs < 1){*pbstrValue = bstrRet.Detach();return S_OK;}int args = pdispparams->cArgs;// C calling convention order of parameters is in reversedCString action = pdispparams->rgvarg[args-1].bstrVal;debugIt(" exec***action:%s:%d ",action,args);if (action == "alert"){CString csMessage;CString csTitle;if (args > 1){csMessage= GetVariantStr(pdispparams->rgvarg[args-2]);}if (args > 2){csTitle = GetVariantStr(pdispparams->rgvarg[args-3]);}MessageBox(m_hWnd, LPCSTR(csMessage), LPCSTR(csTitle), MB_OK);}//else if(action == "什么")//{//}*pbstrValue=bstrRet.Detach(); // 返回值return S_OK;}CExternal::~CExternal()if(m_typeinfo) m_typeinfo->Release();}C++调⽤脚本可以使⽤下⾯的代码,此代码是我在⽹上下载的,具体的来源我已经不记得了,但在⽹上应该可以找到类似的.原理是⽤到了WebBrowser2,但是C++和脚本的相互调⽤都⽤到了HTML页⾯,使⽤HTML页⾯成了包袱,能否丢掉它,我不知道如何实现,望⾼⼿指点.......// 头⽂件#pragma once#include <atlbase.h>#include <Mshtml.h>class CCallScript{public:CCallScript();virtual ~CCallScript();BOOL DocumentSet(){return(m_bDocumentSet);}BOOL SetDocument(IDispatch* pDisp);LPDISPATCH GetHtmlDocument() const;const CComBSTR GetLastError() const;BOOL GetScript(CComPtr<IDispatch>& spDisp);BOOL GetScripts(CComPtr<IHTMLElementCollection>& spColl);BOOL Run(const CComBSTR strFunc,CComVariant* pVarResult = NULL);BOOL Run(const CComBSTR strFunc,const CComBSTR strArg1,CComVariant* pVarResult = NULL);BOOL Run(const CComBSTR strFunc,const CComBSTR strArg1,const CComBSTR strArg2,CComVariant* pVarResult = NULL);BOOL Run(const CComBSTR strFunc,const CComBSTR strArg1,const CComBSTR strArg2,const CComBSTR strArg3,CComVariant* pVarResult = NULL);BOOL Run(const CComBSTR strFunc,const CSimpleArray<CComBSTR> & paramArray,CComVariant* pVarResult = NULL);private:BOOL m_bDocumentSet;protected:void ShowError(CComBSTR lpszText);protected:CComPtr<IHTMLDocument2> m_spDoc;CComBSTR m_strError;};inline void CCallScript::ShowError(CComBSTR lpszText){m_strError = "Error: ";m_strError.Append(lpszText);}inline const CComBSTR CCallScript::GetLastError() const{return m_strError;}inline LPDISPATCH CCallScript::GetHtmlDocument() const{return m_spDoc;}// CPP⽂件#include "stdafx.h"#include "CallScript.h"#define CHECK_POINTER(p)ATLASSERT(p != NULL);if(p == NULL){ShowError("NULL pointer");return FALSE;}const CComBSTR GetSystemErrorMessage(DWORD dwError){CComBSTR strError;LPTSTR lpBuffer;if(!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL, dwError,MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),(LPTSTR) &lpBuffer, 0, NULL)){strError = "FormatMessage Netive Error" ;}else{strError = lpBuffer;LocalFree(lpBuffer);}return strError;}CCallScript::CCallScript(){m_bDocumentSet = FALSE;}CCallScript::~CCallScript(){}BOOL CCallScript::SetDocument(IDispatch* pDisp)CHECK_POINTER(pDisp);m_spDoc = NULL;CComPtr<IDispatch> spDisp = pDisp;HRESULT hr = spDisp->QueryInterface(IID_IHTMLDocument2,(void**)&m_spDoc);if(FAILED(hr)){ShowError("Failed to get HTML document COM object");return FALSE;}m_bDocumentSet = TRUE;return TRUE;}BOOL CCallScript::GetScript(CComPtr<IDispatch>& spDisp){CHECK_POINTER(m_spDoc);HRESULT hr = m_spDoc->get_Script(&spDisp);ATLASSERT(SUCCEEDED(hr));return SUCCEEDED(hr);}BOOL CCallScript::GetScripts(CComPtr<IHTMLElementCollection>& spColl){CHECK_POINTER(m_spDoc);HRESULT hr = m_spDoc->get_scripts(&spColl);ATLASSERT(SUCCEEDED(hr));return SUCCEEDED(hr);}BOOL CCallScript::Run(const CComBSTR strFunc,CComVariant* pVarResult){CSimpleArray<CComBSTR> paramArray;return Run(strFunc,paramArray,pVarResult);}BOOL CCallScript::Run(const CComBSTR strFunc,const CComBSTR strArg1,CComVariant* pVarResult){CSimpleArray<CComBSTR> paramArray;paramArray.Add((CComBSTR &)strArg1);return Run(strFunc,paramArray,pVarResult);}BOOL CCallScript::Run(const CComBSTR strFunc,const CComBSTR strArg1,const CComBSTR strArg2,CComVariant* pVarResult){CSimpleArray<CComBSTR> paramArray;paramArray.Add((CComBSTR &)strArg1);paramArray.Add((CComBSTR &)strArg2);return Run(strFunc,paramArray,pVarResult);}BOOL CCallScript::Run(const CComBSTR strFunc,const CComBSTR strArg1,const CComBSTR strArg2,const CComBSTR strArg3,CComVariant* pVarResult) {CSimpleArray<CComBSTR> paramArray;paramArray.Add((CComBSTR &)strArg1);paramArray.Add((CComBSTR &)strArg2);paramArray.Add((CComBSTR &)strArg3);return Run(strFunc,paramArray,pVarResult);}BOOL CCallScript::Run(const CComBSTR strFunc, const CSimpleArray<CComBSTR>& paramArray,CComVariant* pVarResult){CComPtr<IDispatch> spScript;if(!GetScript(spScript)){ShowError("Cannot GetScript");return FALSE;}CComBSTR bstrMember(strFunc);DISPID dispid = NULL;HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);if(FAILED(hr)){ShowError(GetSystemErrorMessage(hr));return FALSE;}//const int arraySize = paramArray.GetCount();const int arraySize = paramArray.GetSize();DISPPARAMS dispparams;memset(&dispparams, 0, sizeof dispparams);dispparams.cArgs = arraySize;dispparams.rgvarg = new VARIANT[dispparams.cArgs];//__asm {int 3}CComBSTR bstr;for( int i = 0; i < arraySize; i++){bstr.Empty();//CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back readingbstr = paramArray[arraySize - 1 - i]; // back reading//bstr.CopyTo(&dispparams.rgvarg[i].bstrVal); //memory leakdispparams.rgvarg[i].bstrVal = bstr.m_str; //also cause problem when paras are more than 1dispparams.rgvarg[i].vt = VT_BSTR;}amedArgs = 0;EXCEPINFO excepInfo;memset(&excepInfo, 0, sizeof excepInfo);CComVariant vaResult;UINT nArgErr = (UINT)-1; // initialize to invalid arghr = spScript->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);/////////////// bug fix memory leak code start ///////////////// for( int j = 0; j < arraySize; j++)// ::SysFreeString(dispparams.rgvarg[j].bstrVal);/////////////// bug fix memory leak code end ///////////////delete [] dispparams.rgvarg;if(FAILED(hr)){ShowError(GetSystemErrorMessage(hr));return FALSE;}if(pVarResult){*pVarResult = vaResult;}return FALSE;}这两个⽂件的使⽤的⽅法:// Get the browser control.CAxWindow wnd = GetDlgItem(IDC_EXPLORER); // WebBrowserwnd.QueryControl( &m_spBrowser );CComPtr<IAxWinAmbientDispatch> spAmbient;HRESULT hr = wnd.QueryHost(&spAmbient);// diable the context menu// disable the scrollbarif( SUCCEEDED(hr) ){spAmbient->put_AllowContextMenu(VARIANT_TRUE);spAmbient->put_DocHostFlags(docHostUIFlagFLAT_SCROLLBAR);}// navigate to the base htmlVARIANT flag = {0};VARIANT name = {0};VARIANT post = {0};VARIANT head = {0};//// m_spBrowser->Navigate(_bstr_t(GetFullName("WhizConsoleSlave.html")), &flag, &name, &post, &head); TCHAR szFileName[MAX_PATH];::GetModuleFileName(_Module.GetModuleInstance(), szFileName, MAX_PATH);TCHAR szRes[MAX_PATH+10];::wsprintf(szRes, _T("res://%s/%0d"), szFileName, IDR_HTML);CComVariant vURL(szRes);m_spBrowser->Navigate2(&vURL, &flag, &name, &post, &head); // 显⽰指定的页⾯// Create a wrapper about the external dispatch interfaceCComObject<CWrapperDispatch>* spdispWrapper = 0;hr = CComObject<CWrapperDispatch>::CreateInstance(&spdispWrapper);if( FAILED(hr) ) return 0;// Dummy for refcount managementCComPtr<IUnknown> spUnk = spdispWrapper;// Create the object that will handle the external interface for the// html file.pExternal = new CExternal(m_hWnd);m_oExternal = static_cast<IDispatch *>(pExternal);// Set the external dispatch interfacespdispWrapper->SetDispatch(m_oExternal); // 对脚本抛送接⼝hr = wnd.SetExternalDispatch(spdispWrapper);// wnd.SetFocus();// ******************************************************************// 调⽤脚本⽐较容易if ( m_CallScript.DocumentSet() == FALSE){IDispatch* d = NULL;m_spBrowser->get_Document(&d);m_CallScript.SetDocument(d);d->Release();}m_CallScript.Run(L"DisplayStr"); // DisplayStr就是脚本的函数m_CallScript.Run(L"AddDir","a","b"); // AddDir也是脚本的函数,a和b是AddDir的参数.。

Javascript和C#之间的互相调用和访问

Javascript和C#之间的互相调用和访问

Javascript和C#之间的互相调用和访问这包括了JS调用c# ... JS访问C#变量 C# 调用JS代码 C#访问JS 变量的各种 ...JS代码<script language= javascript type = text/javascript >var JSVar = This is JS Code ;function getcsharpstring() {//去调用c#的函数请注意带参数的写法var mys = <%=CSharpString( ___________This is JS Code )%> ;//没有参数的可以这样写var mys = <%=CSharpString()%> ;alert(mys)}function getcsharpvar() {var mys = <%= CSharpVar%> ;//调问c#中的变量alert(mys)}//此函数用于C#调用function CSharpCall() {alert( 这里设置一个ookie );//设置一个cookie 在c#读取这个cookie的值来达到访问JS变量okie = JSVarToCSharp= + JSVar;}</script>c#后台代码public partial class _Default : System Web UI Page{public string CSharpVar = 这是CSharp代码 ;//C#变量protected void Page_Load(object sender EventArgs e){}//被JS调用public string CSharpString(string _string ){return 这是CSharp代码 + _string ;}protected void Button _Click(object sender EventArgs e){string jsString = <script language=javascript > CSharpCall() </script> ;Page RegisterStartupScript( ggg jsString);//调用JS ...}protected void Button _Click(object sender EventArgs e){//通过读取cookie 来得到JS的变量HttpCookie cookie = Request Cookies[ JSVarToCSharp ];if (cookie != null){string jsVar = cookie Value ToString();}//可以用同样的 ... 让JS访问c#代码如下/*c#(加)using System WebHttpCookie UserCookie = new HttpCookie( UserName UserName);Response Cookies Add(UserCookie);(注销)Request Cookies Clear();//将Cookies[ UserName ]置空HttpCookie customerCookie = new HttpCookie( UserN ame string Empty);Response Cookies Add(customerCookie);JSfunction getCookie(objName){//获取指定名称的cookie的值var arrStr = okie split( ; );for(var i = ;i < arrStr length;i ++){var temp = arrStr[i] split( = );if(temp[ ] == objName) return unescape(temp[ ]);}}function delCookie(name){//为了删除指定名称的cookie 可以将其过期时间设定为一个过去的时间var date = new Date();date setTime(date getTime() );okie = name + =a; expires= + date toGMTString();}*/}}lishixinzhi/Article/program/net/201311/13040。

clearscriptv8 使用手册

clearscriptv8 使用手册

clearscriptv8 使用手册第一节:简介ClearScriptV8 是一个用于在.NET 平台上与Google V8 JavaScript 引擎进行交互的库。

它提供了一个简洁易用的接口,使开发人员能够在.NET 环境中轻松地执行JavaScript 代码,并实现JavaScript 与CLR (Common Language Runtime) 之间的无缝互操作。

第二节:安装与配置1. 下载与安装在开始使用 ClearScriptV8 之前,首先需要下载并安装它。

可以在ClearScript 官方网站上找到最新版本的 ClearScriptV8 的安装程序,并按照安装向导进行操作。

2. 配置环境变量在安装完成后,需要为 ClearScriptV8 配置环境变量。

打开“计算机”(或“此电脑”)的属性窗口,选择“高级系统设置”,然后点击“环境变量”按钮。

在系统变量中找到“Path”变量,并在其值的末尾添加ClearScriptV8 安装路径。

第三节:使用示例下面将通过几个示例演示 ClearScriptV8 的基本用法。

1. 创建引擎对象使用以下代码片段创建一个 ClearScriptV8 引擎对象:```csharpusing (var engine = new V8ScriptEngine()){// 在这里执行JavaScript 代码}```2. 执行JavaScript通过调用引擎对象的Execute 方法,可以执行一段JavaScript 代码,并接收返回值:```csharpusing (var engine = new V8ScriptEngine()){var result = engine.Execute("1 + 2");Console.WriteLine(result); // 输出:3}```3. 定义与使用JavaScript 对象在 ClearScriptV8 中,可以从.NET 代码中创建JavaScript 对象,并在JavaScript 代码中使用它们。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JavaScript引擎研究与C、C++与互调用博客分类:软件程式-JavaScriptjavascriptc++脚本1.概要2.Google V82.1. 介绍Google Chrome是google 2008年9月发布的浏览器,Chrome的网页渲染部分使用的是Webkit的渲染引擎,Chrome的JavaScript引擎就是大名鼎鼎的V8了。

V8是C++语言编写的,是开放源码的,是所有的JavaScript引擎中速度最块的。

其开源项目地址为:/p/v8。

V8对外的API接口是C++的接口。

V8的API定义了几个基本概念:句柄(handle),作用域(scope),上下文环境(Context)。

模板(Templates),了解这些基本的概念才可以使用V8。

l上下文环境Context就是脚本的运行环境,JavaScript的变量、函数等都存在于上下文环境Context中。

Context可以嵌套,即当前函数有一个Context,调用其它函数时如果又有一个Context,则在被调用的函数中javascript是以最近的Context为准的,当退出这个函数时,又恢复到了原来的Context。

l句柄(handle)就是一个指向V8对象的指针,有点像C++的智能指针。

所有的v8对象必须使用句柄来操作。

没有句柄指向的V8对象,很快会被垃圾回收器回收了。

l作用域(scope)是句柄的容器,一个作用域(scope)可以有很多句柄(handle)。

当离开一个作用域(scope)时,所有在作用域(scope)里的句柄(handle)都会被释放了。

l模板(Templates)分为函数模板和对象模板,是V8对JavaScript的函数和对象的封装。

方便C++语言操作JavaScript的函数和对象。

l V8 API定义了一组类或者模板,用来与JavaScript的语言概念一一对应。

比如:V8的Function模板与JavaScript的函数对应V8的Object类与JavaScript的对象对应V8的String类与JavaScript的字符对应V8的Script类与JavaScript的脚本文本对应,它可以编译并执行一段脚本。

2.2. C++调用JavaScript使用V8,在C++中访问Javascript脚本中的内容,首先要调用Context::GetCurrent()->Global()获取到Global全局对象,再通过Global全局对象的Get 函数来提取Javascript的全局变量、全局函数、全局复杂对象。

C++代码示例如下://获取Global对象Handle<Object>globalObj = Context::GetCurrent()->Global();//获取Javascrip全局变量Handle<Value>value = globalObj->Get(String::New("JavaScript变量名"));intn = value ->ToInt32()->Value();//获取Javascrip全局函数,并调用全局函数Handle<Value>value = globalObj->Get(String::New("JavaScript函数名"));Handle<Function> func = Handle<Function>::Cast(value) ;//转换为函数Local<Value> v1 = Int32::New(0);Local<Value> v2 = Int32::New(1);Handle<Value> args[2] = { v1, v2 }; //函数参数func->Call(globalObj, 2, args);//获取Javascrip全局对象,并调用对象的函数Handle<Value>value = globalObj->Get(String::New("JavaScript复杂对象名"));Handle<Object> obj = Handle<Object>::Cast(value);//转换为复杂对象Handle<Value> objFunc = obj ->Get(String::New("JavaScript对象函数名"));Handle<Value> args[] = {String::New("callobject function ")};//函数参数objFunc->Call(globalObj, 1, args);2.3. JavaScript调用C++使用V8,在Javascript脚本中想要访问C++中的内容,必须先将C++的变量、函数、类注入到Javacsript中。

注入时,首先要调用Context::GetCurrent()->Global()获取到Global对象,再通过Global对象的Set函数来注入全局变量、全局函数、类对象。

全局变量、全局函数的注入过程与上一节的代码类似,这里就省略不写了。

比较麻烦的是将C++的类、类对象注入到Javascript中。

其基本的过程如下:1.首先定义一个C++类,定义一个类对象指针2.定义一组C++全局函数,封装V8对C++类的调用,提供给V8进行CALLBACK回调。

3.最后调用V8 API,将定义的C++类和C++函数注入到Javascript中在V8的API接口中,还提供了一个“内部数据”(Internal Field)的概念,“内部数据”就是允许V8对象保存一个C++的void*指针。

当V8回调C++全局函数时,C++可以设置或者获取该void*指针。

下面是一个将C++类、类变量注入到Javascript中的C++代码示例。

//一个C++类test、class test{public:test(){number=0;};voidfunc(){number++;}int number;};//一个全局对象g_test//目的是:在Javascript中可以直接使用这个对象,例如g_test.func()test g_test;//封装V8调用test类构造函数//在Javascript中如果执行:var t = new test;V8就会调用这个C++函数//在C++中执行NewInstance函数注入对象时,也会调用这个函数//默认的test类的构造函数没有参数,C++注入对象时,提供一个额外的参数v8::Handle<v8::Value> testConstructor(constv8::Arguments& args){v8::Local<v8::Object>self = args.Holder();//这里假定有两个“内部数据”(Internal Field)//第一个“内部数据”保存test对象的指针//第二个“内部数据”为1 就表示这个对象是由C++注入的//第二个“内部数据”为0 就表示这个对象是JS中自己建立的if(args.Length()){//默认为0,当C++注入对象时,会填充这个“内部数据”self->SetInternalField(0,v8::External::New(0));self->SetInternalField(1,v8::Int32::New(1));}else{self->SetInternalField(0,v8::External::New(new test));self->SetInternalField(1,v8::Int32::New(0));}return self;}//封装V8调用test类func方法//在Javascript中如果执行:t.func();V8就会调用这个C++函数v8::Handle<v8::Value> testFunc(constv8::Arguments& args){//获取构造函数testConstructor时,设置的对象指针v8::Local<v8::Object>self = args.Holder();v8::Local<v8::External> wrap =v8::Local<v8::External>::Cast(self->GetInternalField(0));void* ptr =wrap->Value();//调用类方法static_cast<test*>(ptr)->func();returnv8::undefined();}//封装V8调用test类成员变量number//在Javascript中如果执行:t.number;V8就会调用这个C++函数v8::Handle<v8::Value>getTestNumber(v8::Local<v8::String> property, constv8::AccessorInfo& info){//获取构造函数testConstructor时,设置的对象指针v8::Local<v8::Object>self = info.Holder();v8::Local<v8::External> wrap =v8::Local<v8::External>::Cast(self->GetInternalField(0));void* ptr =wrap->Value();//返回类变量returnv8::Int32::New(static_cast<test*>(ptr)->number);}//C++类和全局的函数定义好以后,就可以开始将类、变量注入V8 Javascript中了//获取global对象v8::Handle<v8::Object> globalObj =context->Global();//新建一个函数模板,testConstructor是上面定义的全局函数v8::Handle<v8::FunctionTemplate> test_templ=v8::FunctionTemplate::New(testConstructor);//设置类名称test_templ->SetClassName(v8::String::New("test"));//获取Prototype,v8::Handle<v8::ObjectTemplate> test_proto =test_templ->PrototypeTemplate();//增加类成员函数,testFunc是上面定义的全局函数test_proto->Set("func",v8::FunctionTemplate::New(testFunc));//设置两个内部数据,用于构造函数testConstructor时,存放类对象的指针。

相关文档
最新文档