续
http://www.blogjava.net/lifesting/archive/2009/06/17/267958.html
下载此例子
4 第一个底层extension
DW采用SpiderMonkey作为Javascript解析器,这是一个C解析器,这意味着如果要在javascript中使用一些系统相关的东西,比如获得当前系统信息如CPU频率,内存大小等,必须使用借助C/C++来开发SpiderMonkey的扩展。
DW针对SpiderMonkey做了一个封装,我们没法知道怎么封装的,只能使用它提供给我们的API来编写底层Extension,本节将以获得一个当前系统内存大小字串为例讲述这个开发过程。它将为javascript注入一个localSystem 对象(为简单,该对象只提供一个方法 getMemorySize)
本节假设你机器上安装有VC开发工具,且熟悉C/C++一些基本概念。我目前使用的是vs 2008,其它版本类似。
step 1: 创建一个名为localSystem的dll工程,new project->visual c++->win32->win32 console application,在applicaton setting上将application type设置为dll,并钩上"exports symbols",如下图
一般对于扩展来说,扩展里面的dll只包含方法代理,具体的实现需要借助其它dll/lib来完成,这很好理解,因为扩展dll与dreamweaver绑定在一起,如果我们把获得内存大小的方法实现放在扩展dll里,那么就其它比如MFC/CPP等应用就不能复用。所以,为把这个例子演示的更像一个产品,会在这个solution里面再创建一个dll,这是一个纯粹的win32 dll。
step 2: 如同step 1在localSystem solution下新建一个名为sysinfo的dll工程。完成之后,solution将会有两个dll 工程,其中localSystem为DW使用,它依赖于sysinfo工程。针对这种依赖关系,需要设置三个地方。
a)打开localSystem project属性设置页面,common properties->add new references,将sysinfo设置为localSystem的reference项目
b)打开localSystem project属性设置页面,configuration properties->c/c++->general->additional include directories,将sysinfo目录加上
c)打开localSystem project属性设置页面,configuration properties->linker,在general->additonl library directories加上sysinfo的输出路径,并且在input->additional dependencies上加上sysinfo.lib
step 3: 完善sysinfo工程。打开sysinfo工程下的sysinfo.h文件,替换如下:
#ifdef SYSINFO_EXPORTS
#define SYSINFO_API __declspec(dllexport)
#else
#define SYSINFO_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
SYSINFO_API void sysMemSize(char*, int);
#ifdef __cplusplus
}
#endif
可以看到,这儿定义了一个sysMemSize方法,用来返回当前内存大小字串。
因为DW扩展只支持C代码,不支持C++,所以需要使用extern "C,同时为了避免范错误,需要把localSystem project设置为C代码输出,如下图:
获得内存大小的方法很简单,打开sysinfo.cpp,替换如下:
1 #include "stdafx.h"
2 #include "sysinfo.h"
3
4 #include <string.h>
5 #include <stdio.h>
6
7 SYSINFO_API void sysMemSize(char *str, int sz)
8 {
9
10 MEMORYSTATUS ms;
11 GlobalMemoryStatus(&ms);
12
13 char vl[5][5] = {"B", "KB", "MB", "GB", "TB" };
14
15 double tm = ms.dwTotalPhys + 655360;
16
17 int n = 0;
18
19 while (tm > 1000){
20 tm /= 1024;
21 n++;
22 }
23
24 sprintf_s(str,sz,"%.2f %s",tm,vl[n]);
25 }
step-4:完善localSystem project。DW不靠头文件来使用扩展方法,它在link期间就将方法的相对地址记住了,即函数名->内存地址映射,所以localSystem project不需要头文件,可以将localSystem.h删除。那localSystem怎么与DW产生关系呢?肯定有头文件才行,不然没法做开发了。打开DW安装目录\sample_files\Extending,将extending_dw.zip解开,把其中以mm开头的三个头文件拷贝到localSystem project中。打开localSystem.cpp,替换成为如下代码:
#include "stdafx.h"
#include "mm_jsapi.h"
#include <string.h>
#include "sysinfo.h"
#define MEM_LEN 50
JSBool jsMemorySize(JSContext *cx, JSObject *obj, unsigned int argc, jsval *argv, jsval *rval)
{
char mem_str[MEM_LEN];
memset(mem_str,'\0',MEM_LEN);
sysMemSize(mem_str,MEM_LEN);
JS_StringToValue(cx,mem_str,strlen(mem_str),rval);
return JS_TRUE;
}
MM_STATE
void
MM_Init()
{
JS_DefineFunction("getMemorySize", jsMemorySize, 0);
}
MM_STATE主要是解决Link DW的问题。可以看到,这儿定义了一个getMemorySize函数,包含0个参数。
step 5: 安装。build localSystem solution,将会在debug目录下面有两个dll,将localSystem.dll拷贝到DW安装目录\configuration\JSExtensions下面;将sysinfo.dll拷贝到系统目录下(system/system32)或者DW安装根目录(根目录下的dll好多就是跟sysinfo.dll干同样的事情,比如xerces-c_2_7.dll xml处理,zlib解压缩等)。一般情况我们将business dll放在DW根目录,将extension dll放在jsextensions目录。
step 6: 使用,打开PART-1所写的hw.js,将sayHi函数修改一下:
function sayHi()
{
var mem_size = localSystem.getMemorySize();
window.alert("Memory size:" + mem_size);
}
重新启动DW,点击test->hello->ok 会看到如下效果:
有了这个有力武器,你在DW中好像可以无所不能:)。
5 DW文档操作
讲了这么多,基本没有交互,大多数情况下,对DW文档(也就是我们编的html/jsp等)操作才是DW Extension重点关注的内容。
PART-3 待续