【转】第7篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:全自动注册与反射方法分析...
作者: 牛A与牛C之间 时间: 2013-12-12 分类: 技术文章 | 2条评论 | 编辑文章
第6篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:自动注册JS脚本+自动反射方法分析
本文转自“吾乐吧软件站”,原文链接:http://www.wuleba.com/?p=23624
感兴趣的,可以加入:WebKit/Blink 内核浏览器开发 QQ交流群:244840771
开发语言为:.NET/C++ 方向
5、 第五种方法,全自动注册与反射方法分析
5.1 实现过程:
(1)、定义一个DemoRenderProcessHandler,继承自CefRenderProcessHandler
(2)、重写DemoRenderProcessHandler里的OnWebKitInitialized ( )事件
(3)、定义一个BindingHandler,继承自CefV8Handler,核心代码
(4)、定义一个UnmanagedWrapper,继承自CefUserData,用来保存操作的对象object、对象属性、对象方法 等信息
(5)、定义一个PropertyAccessor,继承自CefV8Accessor,可通过PropertyAccessor的Get ()、Set ( )方法可以进行存取操作。当前操作的是哪个对象,就可以从这里获取
(6)、定义一个TypeUtil操作类,实现CefV8Value与object类型的相互转换
(7)、定义一个普通的类ExampleObject(这个类跟ExampleBv8Handler一样,只是不再需要继承CefV8Handle)
(8)、在BindingHandler里的Execute ( )事件中,通过反射,自动选择最合适的方法,进行调用,不再需要人工去写,几乎实现全自动
(9)、在OnWebKitInitialized ( )事件里面,调用自己封装的类库,直接访问CefRuntimeEx.RegisterJsObject ( )方法就可以自动注册,并且自动响应操作。
(10)、在 OnContextCreated ( ) 事件里面,进行数据绑定操作,这样,BindingHandler里的Execute ( )事件,才能知道是哪个对象调用的。
(11)、写一个网页,去前台通过JS调用
5.2 核心代码:
这个方法,是完成了前面四种方法后,外加死啃1天CEF的C++代码,发现了原生的JS注册机制,然后重写的,核心思想,依然是采用反射,但这次不需要生成对应的JS脚本代码,只需要直接注册属性、方法(具体注册逻辑,CEF会自动完成,所以不需要考虑,但本质上,CEF实现方式和之前的生成JS脚本是一样的),然后通过反射自动选择最合适的操作方法调用,为了减小文章篇幅,仅列出部分代码。
/// <summary>
/// DemoRenderProcessHandler.cs
/// </summary>
protected override void OnWebKitInitialized()
{
#region 调用自己封装的JS类库
CefRuntimeEx.RegisterJsObject(“exampleObject”, new ExampleObject());
#endregion 调用自己封装的JS类库
base.OnWebKitInitialized();
}
protected override void OnContextCreated(CefBrowser browser, CefFrame frame, CefV8Context context)
{
foreach (var kvp in CefRuntimeEx.GetObjects())
{
BindingHandler.Bind(kvp.Key, kvp.Value, context.GetGlobal()); //绑定方式一
//BindingHandler.Bind(kvp.Key, kvp.Value, context.GetGlobal(), false); //绑定方式二
}
base.OnContextCreated(browser, frame, context);
}
/// <summary>
/// BindingHandler.cs
/// </summary>
/// <summary>
/// 绑定数据并注册对象
/// 说明:已经过滤特殊名称,即不含系统自动生成的属性、方法
/// </summary>
/// <param name=”name”>对象名称</param>
/// <param name=”obj”>需要绑定的对象</param>
/// <param name=”window”>用于注册的V8 JS引擎对象,类似于整个程序的窗口句柄</param>
public static void Bind(string name, object obj, CefV8Value window)
{
var unmanagedWrapper = new UnmanagedWrapper(obj);
var propertyAccessor = new PropertyAccessor();
CefV8Value javascriptWrapper = CefV8Value.CreateObject(propertyAccessor);
javascriptWrapper.SetUserData(unmanagedWrapper);
var handler = new BindingHandler();
unmanagedWrapper.Properties = GetProperties(obj.GetType());
CreateJavascriptProperties(handler, javascriptWrapper, unmanagedWrapper.Properties);
HashSet<string> methodNames = GetMethodNames(obj.GetType());
CreateJavascriptMethods(handler, javascriptWrapper, methodNames);
window.SetValue(name, javascriptWrapper, CefV8PropertyAttribute.None);
}
/// <summary>
/// 创建JavaScript方法
/// </summary>
/// <param name=”handler”>处理程序</param>
/// <param name=”javascriptObject”>经过V8 JS引擎处理后的对象</param>
/// <param name=”methodNames”>方法键值对集合</param>
public static void CreateJavascriptMethods(CefV8Handler handler, CefV8Value javascriptObject, IEnumerable<String> methodNames)
{
var unmanagedWrapper = (UnmanagedWrapper) (javascriptObject.GetUserData());
foreach (string methodName in methodNames)
{
string jsMethodName = StringUtil.LowercaseFirst(methodName);
unmanagedWrapper.AddMethodMapping(methodName, jsMethodName);
string nameStr = jsMethodName;
javascriptObject.SetValue(nameStr, CefV8Value.CreateFunction(nameStr, handler), CefV8PropertyAttribute.None);
}
}
由于这部分代码较多,实现过程相当复杂,所以阐述下具体的实现流程,代码就不贴出来了,感兴趣的可以加入QQ群一起讨论!流程如下:
(1)、新建了一个BindingHandler.cs,这是整个封装的核心代码,继承自CefV8Handler
(2)、新建UnmanagedWrapper、PropertyAccessor、TypeUtil,各种协调操作
(3)、通过反射,找到对应的对象,并提取他的所有属性、方法
(4)、调用自己封装的方法,基于原生方法注册JS属性、方法。CEF提供的原生注册方式,就是这个方法CefV8Value.CreateFunction(nameStr, handler)
(5)、当我网页的上下文对象被创建时OnContextCreated ( ),则会重新触发Bind ( )方法
(6)、当网页的JS访问后台数据时,在BindingHandler里的Execute ( )事件中,通过反射,自动选择最合适的方法,进行调用。
5.3 评价总结:
优势:
(1)、自动注册JS对象
(2)、自动反射调用方法
(3)、彻底解决方法一、方法二、方法三残留的弊端问题
(4)、知道方法来源,所有操作“一对一”,不用担心重复问题
弊端:
(1)、由于C#、Javascript、CefV8Value,三者之间的数据类型存在较大跨度,会导致部分数据类型不工作,所以如果遇到特殊数据,尽可能使用string来操作。
(2)、由于是个人封装,可能存在一些没有考虑到的情况,如有问题,后期再完善。
备忘说明:
(1)、项目里面的代码,只保留了最新的那个第5种方法,不想有太多的“干扰代码,所以其他的“阶段性”成果代码已经被注释起来(公司项目,不提供代码);
(2)、这次封装,已经基本达到预期效果,接下来还要做其他的一些功能进行处理。
(3)、用户计算机必须安装Adobe Flash组件才能播放动画,关于这点,找到3个解决方案:
方法一:安装NPAPI版本的Flash组件(非IE版)之后,才能播放动画。访问 http://get.adobe.com/cn/flashplayer/otherversions/ 选择“Flash Player 11 for Other Browsers”。
方法二:如果想要直接集成到浏览器里去,程序目录下,创建一个“Plugins”文件夹,把“C:\Windows\SysWOW64\Macromed\Flash\NPSWF32_XXX.dll”,把这个DLL放到“Plugins”文件夹里去,就可以了。
方法三:直接注册PPAPI版本的Flash组件,注册语法如下:
“E:\XiliumCefGlueDemo\Bin\Xilium.CefGlue.Demo.WinForms.exe” –ppapi-out-of-process –register-pepper-plugins=”E:\XiliumCefGlueDemo\Bin\PepperFlash\pepflashplayer.dll;application/x-shockwave-flash”
from:http://www.wuleba.com/23626.html
【转】第7篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:全自动注册与反射方法分析...相关推荐
- Xilium.CefGlue的入门
资源地址: 源码:https://gitlab.com/xiliumhq/chromiumembedded/cefglue 官方论坛:http://www.magpcss.org/ceforum/ ...
- Xilium.CefGlue与CEF库的版本匹配关系
今天我试着搭建一个最简单的Xilium.CefGlue项目,这是一个基于CEF3类库的.NET项目 (CEF是Chromium Embedded Framework的简称) ,对WebKit内核进行了 ...
- CEF Xilium.CefGlue 防止浏览器闪退
CEF Xilium.CefGlue在打开网页的时候,经常会死掉闪退,频率有可能会频繁到开几个网页就死掉了,在这种情况下使用CEF来开发自己的浏览器应用程序基本上不可能.笔者经过自己的一些使用经历和在 ...
- C++CLR类库封装Native类库并用C#调用
1.创建Native类库 新建项目->其他语言->Visual C++->Win32控制台应用程序->DLL 添加头文件 添加源文件 选择生成路径生成dll 2.CLR类库封装 ...
- ie9无法获取未定义或 null 引用的属性“indexof”_前端JS基础篇(二)JS基本数据类型和引用数据类型及检测数据类型方法...
JS中的数据类型 (一).基本数据类型(值类型) 1.number:数字 -12.12.5.-12.5 0这些数字都是number: js中增加了一个number类型的数据:'NaN' typeof ...
- 【技术分享篇】Linux内核——手把手带你实现一个Linux内核文件系统丨Linux内核源码分析
手把手带你实现一个Linux内核文件系统 1. 内核文件系统架构分析 2. 行行珠玑,代码实现 [技术分享篇]Linux内核--手把手带你实现一个Linux内核文件系统丨Linux内核源码分析 更多L ...
- Xilium.CefGlue关闭进程卡住,崩溃的问题
最近从61版本升级了cefglue到96版本,升级之后,关闭主进程就卡主,然后过一段时间崩溃: 找了很久不知道是什么原因,无意中搜索到下面这篇文章.终于解决了问题,特地记录一下 CEF关闭或者退出时报 ...
- js中如何得到循环中的点击的这个id_Js篇面试题9请说一下Js中的事件循环机制
虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...
- 拆分js文件_2021入门Webpack,看这篇就够了:Webpack.config.js 解析
这是优妈成长记的第63篇原创 这是一个webpack配置说明 本文是发布在github上webpack-demo的README文件内容.主要对webpack.config.js每一条的注释说明. gi ...
最新文章
- Biztalk 2006 adapter的开发比2004容易的多
- EOS经济系统分析[转载]
- HDU - 4757 Tree(LCA+可持久化trie树)
- rs485接口上下拉_RS485接口EMC电路设计方案
- 程序清单4.1_talkback.c程序_《C Primer Plus》P60
- cpu使用率_单片机里面的CPU使用率是什么鬼?
- 有些卖花生的人6.5元拿货,却卖6元,这是怎么回事?求解?
- 阿里员工自愿加班却遭同事骂!网友们炸锅了
- 制作Linux的优盘启动盘
- 三屏版知识竞赛类软件的开发需求分析及技术构思
- ASP.NET 2.0 探针
- 软件著作权算法软件设计说明书_软件著作权设计说明书范本.doc
- 「武汉理工大学 软件工程复习」第三章 | 软件需求
- mysql choose when_mybatis使用choose when
- 解决 Windows 商店 0x800704cf 网络问题
- pascal编程语言介绍
- 【视点】从一些实例看大数据部门的权与责
- IOS设备使用Airplay投屏到Windows的软件对比
- 阿里云联合广东办政务数据创新大赛 用人工智能接管卫星做国土监察
- 一元和二元的泰勒展开式
热门文章
- php session有什么用,session有什么作用?
- 9 pcb螺丝焊盘打很多小孔_PCB板设计的10个基本设计流程
- R7-5 求矩阵各行元素之和 (15 分)
- java biginteger log_java – BigInteger:计算可伸缩方法中的小数位数
- 6-7 jmu-Java-07多线程-Thread (3分)
- 回文判断(栈+队列)
- html 解析 qt,windows下用QTwebkit解析html
- mysql 填充结果,mysql为测试数据库填充大量数据
- c语言程序设计基础项目教程,C语言程序设计基础项目教程
- cocos2dx热更新tmx的一个坑