AVEVA PMLNet Guide
Abstract. AVEVA PMLNet allows you to instantitate and invoke methods on .NET objects from PML proxy objects. The PML proxy objects behave just like any other PML object. The paper gives a hello world example to demenstrate the PMLNet usage.
Key Words. AVEVA, PMLNet, PML, AVEVA .Net, C#, Managed C++
1. Introduction
AVEVA PMLNet允许在PML代理对象中实例化或调用.Net对象的方法。代理PML对象的定义通过.NET类运行时创建出来,其与.Net类有类似的方法;代理PML类方法的参数只能是指定的几种,这几种类型的参数与.Net类型对应。代理PML对象的用法及功能表现与其他PML对象相同。
可被PML调用的组件(即动态库dll)通过命令IMPORT加载到AVEVA PDMS/Marine中来。组件可由任意.Net语言来定义,例如:Managed C++(托管C++)、C#或VB .NET等。PMLNet通过反射(reflection)来加载指定的组件。PMLNet引擎(Engine)只会加载包含有自定义属性标记PMLNetCallable的组件中的类和方法。为了在.Net类中定义代理PML类必须满足一定的条件(rules)。
综上所述,在满足PMLNet一定条件下创建的.Net组件中的类是可以被PML使用的,即可以在PML代码中调用.Net组件中的资源。通过这种方式,可以获得以下几点优势:
v 在简单易学的PML中使用.Net库中的海量资源,如Excel的读写库等;
v 程序关键部分用.Net实现,代码的保密性相对PML而言要好很多;
v 由于PMLNet引擎支持.Net的组件,即C++、VB.Net写的库都可以被PML调用;
本文主要通过一个简单例子来说明PML代理类的定义方法,掌握后可以扩展到在PML中使用托管C++,代码保密性更好且速度更快。这样就可以在PML中应用更广泛的资源,来提高程序的开发效率。
由于本人水平所限,文中的错误不妥之处在所难免,敬请不吝指教,将不胜感激。欢迎讨论交流,共同进步。
2.Design Details
下图所示为如何在PDMS/Marine中使用PMLNet实现自定义。有一些.NET API可以用来访问当前数据库任务,显示列表drawlist,几何geometry和其他功能。用户可以通过C#的API来访问PDMS/Marine,但是直接在C#中调用PML是不可能的(It is not possible to directly to call PML from C#)。然而AVEVA提供了一个事件机制来允许PML去订阅(subscrible)C#发出的事件(events),如下图虚线所示。
Figure 2.1 Using PMLNet
使用PMLNet有如下限制:
v 只有标记了PMLNetCallable且满足一定条件的.Net类才能被PML调用;
v 模块切换并不保留.NET对象,核心的C++或FORTRAN对象在模块切换时也不会被保留;
v PML调用.NET方法时只能传入指定类型的变量,其他类型不支持,如DIRECTION, ORIENTATION等;
v 在.NET中调用PML是不允许的,唯一的办法就是通过.NET的事件来调用PML;
v It is not possible to enter ‘partial’ namespaces as you might in C# and expect them to be concatenated;
并不是所有的PML对象都可以传递到所调用的.NET方法中去,只有下表的PML类型的变量可以传递到调用.NET对象的方法中去:
Figure 2.2 Only PML variables types maybe passed to methods of .NET class
3.Using PMLNet
AVEVA提供了一个简单的PMLNet例子,程序名为PMLNetExample,将这个例子的代码例出如下所示:
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using Aveva.PDMS.PMLNet;
namespace Aveva.Pdms.Examples
{
[PMLNetCallable()]
public class PMLNetExample
{
[PMLNetCallable()]
public event PMLNetDelegate.PMLNetEventHandler PMLNetExampleEvent;
[PMLNetCallable()]
public PMLNetExample()
{
}
[PMLNetCallable()]
public void Assign(PMLNetExample that)
{
// No state
}
[PMLNetCallable()]
public void RaiseExampleEvent()
{
ArrayList args = new ArrayList();
args.Add( " ExampleEvent " );
if (PMLNetExampleEvent != null )
PMLNetExampleEvent(args);
}
[PMLNetCallable()]
public void Method()
{
MessageBox.Show( " Called Method " );
}
}
}
如上述代码所示,需要暴露给PML的方法或属性都要标记上PMLNetCallable。将上述代码编译后生成一个组件放到PDMS/Marine的安装目录下,就可以写一个PML小程序来测试效果了。
在CommandWindow中输入如下图所示的命令:
Figure 3.1 Using PML proxy object in PML
在PML中使用代理PML对象主要分为以下步骤:
v 使用IMPORT命令导入组件;
其中PMLNetExample是生成的dll组件名;
v 引入命名空间;
命名空间的名称与C#中命名空间对应;
v 实例化类对象;
实例化类对象的方式与其他PML对象一样。
v 调用对象方法;
调用对象的方法也和PML对象一样,得到结果如下图所示:
Figure 3.2 Test PML proxy object method
4.Rules for Calling .NET
想要在PML中调用.NET类对象,就必须遵守一定的规则。这些规则如下:
v 可被PML调用的.NET组件必须由PMLNetCallable标记且位于%PDMSEXE%目录中;
v .NET组件中只有类可以被PML使用,结构体、接口及枚举除外;
v .NET组件中需要被PML调用的类必须由PMLNetCallable标记;
v .NET组件中需要被PML调用的方法必须由PMLNetCallable标记;
v .NET组件中需要被PML调用的方法的参数类型必须为指定的几种类型;
Figure 4.1 Only PML variables types maybe passed to methods of .NET class
v .NET组件中需要被PML调用的类和方法必须是公有的;
v .NET组件中需要被PML调用的方法不支持默认参数的定义;
v .NET组件中需要被PML调用的类和方法名称是区分大小写的;
v .NET组件中需要被PML调用的类中必须要有Assign()方法;
v .NET组件中需要被PML调用的类必须有一个由PMLNetCallable标记的公有的默认构造函数;
如果没有遵守上述条件之一,当加载相应的组件时就会报出错误,错误信息如下所示:
5.Conclusion
综上所述,在PML中调用.NET组件中的类还是很方便的,只要满足PML代理类定义的一些规则就可以了。
由于.NET组件中的类是由.NET语言实现的,所以托管C++、C#及VB.NET编写的组件都可以包装成代理PML类,进而被PML调用。这种方式就更加扩大了PML可使用的资源,如C++的库都可以在PML中使用,且代码更保密,不易查看源码。
在PML中调用.NET组件中类是可行的,但直接在C#中调用PML却是不可行的。AVEVA也提供了在C#中调用PML的方式:即通过事件订阅,详细请参考文档。
6. References
1. AVEVA .NET Customisation User Guide
2. Example of PML Callable: PMLNetExample
3. AVEVA Software Customisation Guide
4. AVEVA Software Customisation Reference Manual
5. AVEVA Data Access Routines User Guide
PDF Version: AVEVA PMLNet Guide