BaNg@taobao

Just Do It!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  20 Posts :: -1 Stories :: 202 Comments :: 0 Trackbacks
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 待续





posted on 2009-06-18 17:02 Always BaNg. 阅读(1350) 评论(2)  编辑  收藏 所属分类: Java

Feedback

# re: Hello, dreamweaver! (PART 2) 2009-06-18 18:51 简单的牛牛
期待~~~~期待~~~~正想研究一下呢~~~  回复  更多评论
  

# re: Hello, dreamweaver! (PART 2) 2009-06-19 12:48 liudecai_zan@126.com
佩服
  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: