續
http://www.tkk7.com/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 待續