听说UiBot支持C++语言扩展,具体要怎么操作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了听说UiBot支持C++语言扩展,具体要怎么操作?相关的知识,希望对你有一定的参考价值。

UiBot本身的部分代码就是基于微软的.Net框架,用C#语言编写的。所以,也可以用C#语言编写UiBot的插件(以下简称为.Net插件)。实际上,微软的.Net框架支持多种编程语言,包括VB.Net、C++/CLI等等,这些编程语言都遵循.Net框架的规范,它们都可以用来编写.Net插件,但因为C#是微软主推的编程语言,所以本文用C#举例,有经验的读者亦可将其移植到.Net框架上的其他语言。另外,UiBot对.Net插件的支持也是在不断升级的,本文以UiBot Creator 5.1版为例,如果在老版本的UiBot上,一些例子可能无法正常运行,请及时升级。

为了方便您用C#语言写.Net插件,我们设计了一个插件的模板,并将其源码放在GitHub上,点击这里即可获取。如果您习惯使用git,也可以从这个URL拉取:https://github.com/Laiye-UiBot/extend-example。建议您在写.Net插件的时候,直接在这个模板的基础上写,而无需从头开始。后续讲述的内容,也将围绕这个模板中的例子展开。

和Java插件类似,.Net插件也需要编译成扩展名为.dll的文件,才能被UiBot使用。微软的集成开发环境Visual Studio兼具编写和编译的功能,并且也提供了免费的社区版,推荐下载使用。我们提供的模板是基于Visual Studio 2015版本的,您可以选择这个版本,也可以选更高版本的Visual Studio,但不建议使用低于2015版本的Visual Studio。

安装了Visual Studio,并下载了我们的.Net插件模板后,可以双击UiBotPlugin.sln文件,这是一个“解决方案”,名字起得很唬人,实际上就是多个相关联的文件的集合。用Visual Studio打开这个解决方案后。可以看到,里面包含了很多内容,其中唯一需要我们动手修改的是UiBotPlugin.cs文件,其他的文件、引用、Properties等都可以不去动。如下图:

.Net插件的模板

在UiBotPlugin.cs文件里,有一个叫UiBotPlugin的命名空间,其中包含了一个接口(interface)和一个类(class)。为了避免混淆,我们推荐把这个命名空间的名字改为您的插件名。比如最终的插件文件是DotNetPlugin.dll,那么插件名就是DotNetPlugin,这个命名空间的名字也改为DotNetPlugin为宜。

从模板中可以看出:在接口里面声明了三个函数,在类里面写了这三个函数的实现。这三个函数都是例子,您随时可以把它们的声明和实现都删掉,加入您自己的插件函数。但请特别注意:在加入函数的时候,也要保持类似的写法,需要在接口中声明,在类中实现,否则,UiBot不能正常识别这个插件函数。

我们用例子中的Add函数为例,尝试编译插件,并在UiBot中调用这个函数:

    选择Visual Studio的“生成”(Build)菜单项,编译这个解决方案之后,会看到在插件的目录下有个叫Release的目录,里面产生了一个叫UiBotPlugin.dll的文件。

    把这个文件手动改名为您的插件名,并保留.dll的扩展名。如改名为DotNetPlugin.dll。

    把这个文件放到UiBot的extend/DotNet目录下。

    打开UiBot,新建一个流程,在源代码视图写入代码:

    Traceprint DotNetPlugin.add(1, 1)

    运行此流程,结果如下所示,代表插件调用正常。

    .Net插件运行结果

    您可能注意到了,在前面的Python插件、Java插件的例子中,都有Add这个例子函数,而除了插件名之外,UiBot调用它们的方式和运行结果都没有区别。实际上,不同的插件内部实现是有很大差异的,比如在Python语言里,默认用UTF-8编码来保存字符串,而在.Net里默认用UTF-16保存。但UiBot已经帮您抹平了这些差异,让您在使用的过程中不必关心这些细节。

    9.3.2 插件API

    和Python、Java插件类似,在.Net插件中,也可以使用插件API,反过来调用UiBot的一部分功能。如果要调用插件API,只需要基于UiBot提供的模板编写插件即可,无需做其他任何设置。

    .Net插件中能使用的插件API的名字、参数和含义都和Java插件完全一致,例如,可以用UiBot.API.IsStop()来检测当前流程是否需要马上停下来,等等。请参考Java插件的中关于插件API的讲解,不再赘述。

    在模板中,您可能会看到一个名叫DotNetAdapter.dll的文件。实际上,这个文件是UiBot每个版本都包含的。从UiBot 5.1版开始,您调用的.Net版的插件API,实际上都在这个文件里面实现。因此,当您的插件发布的时候,并不需要包含这个文件,因为UiBot已经自带了。

    同时,如果您的UiBot更新到了更高的版本,DotNetAdapter.dll中也可能会包含了更多的插件API。您可以自行从UiBot中拿到新版本的DotNetAdapter.dll文件,并放在您编写的插件的源代码所在的目录下,即可使用到新版的插件API。

    9.3.3 变量的传递

    和Java类似,C#.Net也是静态类型的编程语言,变量在使用之前需要先定义,且定义时必须指定变量的类型。而且,数组中通常只能包含同一种类型的数据。这与UiBot的动态类型有很大的不同。

    因此,在编写和使用.Net插件的时候,需要符合以下规定:

    对于整数、浮点数、字符串、布尔类型等基本类型的参数,UiBot对.Net插件的类型检查不是很严格,它会尽量进行转换,即使转换不成功,也不会报错。所以,请在使用时特别留意每个参数的类型,避免传入了不正确的值,而没有及时发现。

    如果需要把字典或数组类型从UiBot中传到.Net插件中,.Net插件中的参数类型只能使用Newtonsoft.Json.Linq.JArray(对应数组)或者Newtonsoft.Json.Linq.JObject(对应字典)。在模板中,由于我们已经写了using Newtonsoft.Json.Linq;,所以可以省略前缀,简写为JArray(对应数组)或JObject(对应字典),下文亦使用此简化写法。

    如果需要把字典或数组类型从.Net插件中传到UiBot中,.Net插件中的返回值类型只能使用JArray(对应数组)或JObject(对应数组)。UiBot会自动把JArray类型的返回值转换成UiBot中的数组,而把 JObject类型的返回值转换成UiBot中的字典。

    无论传入参数,还是返回值,这些复合类型在.Net插件和UiBot之间都采用值传递的方式,而不是引用传递的方式。

    在插件模板中,有一个作为例子的Concat函数,用于演示如何把两个数组从UiBot传到.Net插件中,又如何把两个数组连接后的结果返回到UiBot中。建议读者仔细阅读。

    9.3.4 插件的引用模块

    UiBot本身是依赖于.Net Framework的,并且假设用户已经安装了.Net Framework 4.5.2(含)以上的版本。如果没有安装.Net Framework,或者版本不对,UiBot本身都不能运行,当然就更不能使用您编写的插件了。所以,在编写插件的时候,只要您的插件依赖的也是.Net Framework 4.5.2版本,就不必担心环境不匹配的问题。

    微软已经在.Net Framework里面内置了非常丰富的功能,但难免有的功能仍然没有包含,需要引用第三方的.Net dll文件。

    和Java插件类似,UiBot在加载一个.Net插件的时候,如果这个.Net插件引用了其他第三方的.Net dll文件,UiBot首先会试图到.Net插件所在的目录下去搜索被引用的dll文件。如果没有找到,还会再到<插件名>.lib这个目录下去找一次。比如,我们有个.Net插件,名为A.dll,放置在extend/DotNet目录中,且引用了B.dll。那么UiBot会先尝试找extend/DotNet/B.dll,再尝试找extend/DotNet/A.lib/B.dll。如果这两个目录下都没有找到,会抛出异常。

    9.3.5 其他注意事项

    JArray和JObject并不是.Net Framework里面自带的,而是使用了开源的Json.Net。在编译和运行的时候,都需要依赖一个名为Newtonsoft.Json.dll的文件。 在UiBot提供的模板中,已经包含了这个文件。同时,在每个版本的UiBot中,也会自带这个文件。因此,您可以直接使用JArray和JObject,而并不需要把这个文件包含在插件当中。

    在编译插件的时候,编译器可能会警告“DotNetAdapter的处理器架构不匹配”之类的信息。实际上没有影响,无需理睬这个警告。

    .Net插件中的函数支持默认参数。在调用时,如果某些参数有默认值,则可以不传值,此参数会自动取默认值。

    可以在.Net插件的函数中抛出异常,异常可以由.Net插件自行捕获,也可以不捕获。如果.Net插件不捕获,那么异常会自动被传到UiBot中,UiBot可以捕获。 如果UiBot也不捕获,那么流程的运行会出错退出,并且会在出错信息中说明是由于.Net插件中的异常导致的,以便排查问题。

    .Net中的变量、函数都是区分大小写的,但在UiBot中使用.Net插件时,仍然可以不区分大小写的调用其中的函数。比如,在前面的例子中,可以在UiBot中写DotNet.add(1,1),也可以写dotnet.ADD(1,1),其效果完全一样。

参考技术A 你可以去社区看看哈,有很完整的教程呢~而且不止支持C++,Python,LUA,.net都可以的呢~本回答被提问者采纳 参考技术B 随着U盘的不断普及,高速USB3.0时代也随之到来,对于刚入手的U盘,如何辨别是否支持USB3.0高速传输呢?下面小编就将大家一起来探讨一下USB2.0与USB3.0的区别及辨别方法。

使用pybind11开发python扩展库

当我们使用python的类时,可以动态地添加属性到类里去,这是基本的工作机制,但是在C++语言里的类是固定的,也就是说在编译之后是固定的,不会变化。因此要想让C++里导出的类支持python这种特性,必须有一些改变才可以。现在就来搞明白怎么样让C++里导出的类支持这个特性。

这时需要引入使用py::dynamic_attr()特性,经过它处理之后,就可以让C++类导出之后具备动态添加成员变量的功能,声明如下:

	py::class_<MyPet>(m, "MyPet", py::dynamic_attr())
		.def(py::init<const std::string &>())
		.def_property("name", &MyPet::getName, &MyPet::setName);

而类MyPet定义如下:


class MyPet {
public:
	MyPet(const std::string &name) : name(name) { }
	void setName(const std::string &name_) { name = name_; }
	const std::string &getName() const { return name; }
private:
	std::string name;
};

可见在这个类没有声明任何特别的类型,就可以在python里使用了,如下来测试一下:

#演法动态属性
p = TestAdd.MyPet

以上是关于听说UiBot支持C++语言扩展,具体要怎么操作?的主要内容,如果未能解决你的问题,请参考以下文章

UiBot无法抓取Google Chrome元素和数据抓取工具无法使用的解决方案

c++的接口是怎么实现的?

Eclipse CDT 编辑器支持 altivec C++ 扩展?

听说Oracle 发布了一个全栈虚拟机 GraalVM,支持 Python!

使用pybind11开发python扩展库

听说2017年最火的数据库是MongoDB?