VFP7 與 Web Service

前言
建立Web Service
建立Web Service Client 端程式
使用其他語言建立的 Web Service
與資料庫結合
結論
參考資料
前言
VFP 這項產品一直被謠傳微軟將不再支援,但在今年六月,微軟將VFP7自Visual Studio.NET中獨立出來銷售,總算是打破了這個謠言。此外,也為這項產品添加了不少功能,比如 Intellisense、對COM的更完整支援、SOAP與Web Service 等等。這裡就為各位解說新增的SOAP與Web Service功能。
SOAP 與 Web Service 這兩個名詞,相信我不用再多做解釋了,大家在這一陣子的耳濡目染之下,應該都大致了解,在此就不再贅述。如果想了解的人請參考前幾期RUN!PC李維老師的文章,有詳細的解說。

建立Web Service
首先讓我們來製作 Web Service,稍後,再來撰寫如何使用 Web Service 的 Client 端程式。
要使用VFP7製作Web Service之前,請先在[Internet 服務管理員]中,新增一個虛擬目錄,在此,我們先命名為 WebServices。
接下來得製作一個COM元件,在這裡我們就以一個簡單的相加函數來作為一個範例。
請先建立一個新專案,名稱叫做MyWebService,在Project Manager(專案管理員)中,切換到 Program頁籤,點選 ”New”,將下列這段程式碼貼到裡面去,然後存檔為 prog1.prg。

DEFINE CLASS MyCalculator AS session OLEPUBLIC
Name = "MyCalculator"
PROCEDURE doAdd
Parameters A , B
Return A+B
ENDPROC
ENDDEFINE

這一段程式碼只是將傳入的兩個參數做一個簡單的相加而已。
接著就要進行編譯的工作了,點選”Build”,建立的型態選為”Single-threaded COM Server(dll)”,按下 ”確定” 來建立一個dll型態的COM伺服器。
image002.jpg
建立完成後,你會發現VFP7為你產生了一個mywebservice.dll,並已經為你註冊到電腦中了,讓我們驗證一下VFP7是否已經編譯成功,請在命令列中依序輸入:

obj=createobject(“MyWebService.MyCalculator”)
? obj.doAdd(100,100)

如果成功的話,你應該會看到VFP7回應了 200 這個答案,表示COM伺服器已經建立成功。
VFP7提供了一個方便的精靈,讓你可以直接在VFP7的整合環境中建立 Web Service,而不需要另外去執行 SOAP toolkit 來製作。
請你在Project Manager中,以滑鼠右鍵點選叫出快捷選單,選擇Builder。此時,會出現一個選擇精靈的對話方盒(如圖),選擇Web Services Publisher,並按下確定。
image004.jpg
接著會出現Web Services Publisher這個對話盒(如圖),我們按下 “…” 按鈕,去搜尋我們剛剛建立的MyWebService.MyCalculator COM伺服器。找到並確定之後,再按下”Advanced”,讓我們看看可以再多做些什麼設定。
在 Advanced 設定中,我們可以指定

  1. WSDL 產出的位置。
  2. SOAP Listener型態。
  3. IntelliSense的Script名稱。
  4. 告訴VFP7在Project Build之後,是否自動產出相關的 Web Service 檔案。
  5. 產出的WSDL檔案是否要以UTF-16 Unicode作為預設編碼。
    image006.jpg
    image008.jpg
    image010.jpg
    image012.jpg

在確定所有設定無誤之後,按下 Generate,Web Service Publish精靈就會利用SOAP toolkit為我們在指定的位置產出Web Service的相關檔案。

Web Service Client 程式
那麼,我們要如何使用這個 Web Service 呢?
讓我們寫一個簡單的 form 來呼叫
請開一個新檔案,類型選為Form (表單),在表單裡面放置一個按鈕(如下圖),在按鈕的OnClick事件內放置如下的程式碼:

x = CREATEOBJECT("MSSOAP.SoapClient")
x.MSSoapInit("http://ellery/webservices/MyCalculator.WSDL", , "MyCalculatorSoapPort")
=messagebox( str( x.doAdd( 100,100 ) ) )

執行這個表單,在click按鈕之後,你會發現你並沒有辦法呼叫!!是VFP7的bug嗎??
首先,因為soap物件會利用 wsdl 檔案做 Initialization 的動作,所以我檢查了一下產出的 wsdl:

…略…
<message name='MyCalculator.doAdd'>
</message>
<message name='MyCalculator.doAddResponse'>
<part name='Result' type='xsd:anyType'/>
</message>
…略…

在這裡 SOAP toolkit wizard 並沒有為我們的 COM 元件產生參數的宣告。
產出的 WSDL 碼應該是下面這樣子才對的呀.

…略…
<message name='MyCalculator.doAdd'>
<part name='A' type='xsd:int'/>
<part name='B' type='xsd:int'/>
</message>
<message name='MyCalculator.doAddResponse'>
<part name='Result' type='xsd:anyType'/>
</message>
…略…

為了這個疑惑,我將問題貼到 Microsoft Newsgroup(http://communities.microsoft.com/newsgroups/default.asp) 和 Universal Thread(http://www.universalthread.com) 網站去詢問,過了兩天,就有了結果,兩個地方給我的回答都是相同的,我們必須將PROCEDURE doAdd 的宣告修改為

PROCEDURE doAdd(A as Integer, B as Integer)

並把 parameters 敘述移除。
修改後,重新 Build、利用 Wizard 發布之後,再執行剛剛我們建立好的 client 端Form,你應該就可以看到Web Service 被起始後的結果了。

使用其他語言建立的web service
為了驗證一下,VFP也能使用其他語言或其他平台上建立的 Web Service,我們仿效李維老師於RUN!PC 90 期文章中所寫的範例,寫一個取得溫度的簡單範例。
請依照下圖來製作一個表單:
image014.jpg
然後,在”取得溫度”按鈕的 onclick 事件中,置入下列程式碼:

LOCAL obj
obj = CREATEOBJECT("MSSOAP.SoapClient")
obj.MSSoapInit("http://www.xmethods.net/sd/2001/TemperatureService.wsdl")
thisform.text2.value=obj.getTemp(thisform.text1.value)

在執行這個表單之後,在州代號的欄位中,輸入 07060,再按下 “取得溫度” 按鈕,下面的當地氣溫欄位便顯示出氣溫,表示可以正確的呼叫!
image016.jpg

與資料庫結合
VFP為了因應 XML 的流行,在這個版本中添加了與XML 相關的三個函數:CURSORTOXML()、XMLTOCURSOR()、XMLUPDATEGRAM(),正好可以用來在 Web Services 中傳遞資料。
請在Project Manager中,新增一個程式檔(program),然後將下列的程式碼加入,並命名為 prog2.prg:

DEFINE CLASS tastrade AS session OLEPUBLIC
Name = "tastrade"
PROCEDURE getAllEmployee()
LOCAL handle as Integer
LOCAL lc_xml as String
handle=SQLSTRINGCONNECT("Driver=Microsoft Visual FoxPro Driver;” + ;
“UID=;PWD=;” + ;
“SourceDB=C:\WebService\Data\testdata.dbc;” + ;
“SourceType=DBC;Exclusive=No;BackgroundFetch=Yes;” + ;
“Collate=Machine;Null=Yes;Deleted=Yes;")
=SQLEXEC(handle, ;
"select emp_id, last_name, first_name, title from employee order by emp_id", ;
"employees")
=sqldisconnect(handle)
CursorToXML("employees", "lc_xml")
RETURN lc_xml
ENDPROC
PROCEDURE updateEmployee( c_request as string )
LOCAL handle
LOCAL o_xmlDom, o_nodelist1, o_nodelist2, o_nodeEmployee, o_node
LOCAL strWhere as String , strSet as String , strSql as String
LOCAL ll_cycle as Boolean , ln_ret as Integer
c_request=STRTRAN( c_request, 'encoding="Windows-1252" ', "" )
o_xmlDom=CreateObject("Microsoft.XMLDOM")
o_xmlDom.async="false"
o_xmlDom.loadXML(c_request)
* parse xml and combine update-sql syntax
IF o_xmlDom.hasChildNodes()
ELSE
RETURN
ENDIF
* create connection
handle=SQLSTRINGCONNECT("Driver=Microsoft Visual FoxPro Driver;” + ;
“UID=;PWD=;” + ;
“SourceDB=C:\WebService\Data\testdata.dbc;” + ;
“SourceType=DBC;Exclusive=No;BackgroundFetch=Yes;” + ;
“Collate=Machine;Null=Yes;Deleted=Yes;")
strWhere=""
strSet=""
l_cycle=.F.
for each o_nodelist1 in o_xmlDom.documentElement.childNodes
FOR EACH o_nodelist2 IN o_nodelist1.childNodes
* initialize variables
if o_nodelist2.nodeName="updg:before"
FOR EACH o_nodeEmployee IN o_nodelist2.childNodes
FOR EACH o_node IN o_nodeEmployee.childNodes
IF o_Node.nodeName="emp_id"
strWhere=strWhere+o_Node.nodeName+"="+"'" + ;
TRANSFORM(o_Node.text,"@J 999999") + "' and "
ELSE
strWhere=strWhere+o_Node.nodeName+"="+"'" + ;
o_Node.text + "' and "
ENDIF
NEXT
NEXT
ENDIF
IF o_nodelist2.nodeName="updg:after"
IF NOT o_nodelist2.hasChildNodes()
ELSE
FOR EACH o_nodeEmployee IN o_nodelist2.childNodes
FOR EACH o_node IN o_nodeEmployee.childNodes
IF o_Node.nodeName="emp_id"
strSet=strSet+o_Node.nodeName+"="+"'" + ;
TRANSFORM(o_Node.text,"@J 999999") + "',"
ELSE
strSet=strSet+o_Node.nodeName+"="+"'" + o_Node.text + "',"
ENDIF
NEXT
NEXT
ENDIF
l_cycle=.T.
ENDIF
IF l_cycle = .T.
* generate sql syntax
strWhere=LEFT(strWhere,LEN(strWhere)-4)
IF EMPTY(strSet)
strSql="Delete from employee where "+ strWhere
ELSE
strSet=LEFT(strSet,LEN(strSet)-1)
strSql="Update employee set " + strSet + " where " + strWhere
ENDIF
* call sqlexec() to send update-sql
* and we can update our database
ln_ret=SQLEXEC(handle,strSql)
l_cycle=.F.
strWhere=""
strSet=""
ENDIF
NEXT
NEXT
* disconnect
=sqldisconnect(handle)
ENDPROC
ENDDEFINE

這段程式碼裡面包含了一個類別,類別裡面包含了兩個方法:
getAllEmployee 利用 SPT 這組函數取得所有員工的員工編號、姓、名以及職稱,然後再利用 CURSORTOXML() 函數將 Cursor 資料轉換為 XML並傳回。
UpdateEmployee 則依據傳來的 update xml 資料作分析並更新。
再依照之前建立 Web Service 的步驟再做一次 Build COM 元件以及發布的動作。
接著,讓我們來撰寫 client 端的畫面,請依照下圖放置一個 Grid 控制項還有兩個 Button 控制項,然後同樣地,將下列的程式碼分別置放到兩個按鈕的 onclick 事件中。
image017.jpg
在 Retrieve 按鈕的 onclick 事件中置放如下程式碼:

LOCAL x as Object , lc_xml as String
*因為在[Update]按鈕中的 xmlupdategram() 函數需要設製 buffermode 並將 multilocks 設為 True
SET MULTILOCKS ON
IF USED("employee")
thisform.grid1.RecordSource=""
USE IN employee
ENDIF
x = CREATEOBJECT("MSSOAP.SoapClient")
x.MSSoapInit("http://ellery/webservice/tastrade.WSDL")
lc_xml=x.getAllEmployee( )
XMLToCursor(lc_xml,"employee")
thisform.grid1.RecordSource="employee"
thisform.Refresh()
SELECT employee
=CURSORSETPROP("buffering",5)

在 Update 按鈕的 onclick 事件中置放:

LOCAL lc_ret
LOCAL x, lc_xml
*檢查是否已經取得資料
IF NOT USED("employee")
=MESSAGEBOX("[Retrieve] button not pressed!")
RETURN
ENDIF
*產生異動的 xml
lc_ret=XMLUPDATEGRAM("employee")
IF EMPTY(lc_ret)    &&如果沒有異動,發出警告
=MESSAGEBOX("You don't update any thing")
ENDIF
=MESSAGEBOX(lc_ret,"XMLUPDATEGRAM() generates following codes")
*將資料更新回去!
x = CREATEOBJECT("MSSOAP.SoapClient")
x.MSSoapInit("http://ellery/webservice/tastrade.WSDL")
x.updateEmployee( lc_ret )
SELECT employee

然後將這個表單命名為 form2,然後讓我們執行這個表單。
當我們按下 Retrieve 時,這個 client 端的表單就會為我們取回 Server 端的XML資料,並利用 XMLTOCURSOR() 轉換為 Cursor,以便能順利與 VFP 的控制項結合。
當按下更新的時候,我們也能利用 XMLUPDATEGRAM() 函數取得需要更新的必要資料,送回 Server 端,讓 Service 端能根據這份資料來更新資料。

結論
VFP 在7.0版之後就不再被包含在 Visual Studio.NET 之中,但是,VFP開發小組承諾會繼續為這個產品添加更多的功能以迎合使用者的需求。就我個人而言,對 VFP 仍懷有一份特殊的情感,尤其是在使用其他語言開發資料庫時,有時候仍然會忍不住有 “唉!怎麼沒有這個功能,VFP就有” 這個想法,所以我還是會繼續看相關的 VFP 資料。
不過,我感覺到微軟雖然對 VFP 的使用者作出了相當的承諾,可是,從 5.0 到 6.0 到 7.0 ,除了使用者介面與開發COM元件的支援外,其實並沒有什麼太大的改進,我想很多人也會和我有一樣的看法吧。

參考資料:
MSDN – Walkthrough: Creating Web Services with Visual FoxPro
RUN!PC 90 期
XML 網頁製作徹底研究 旗標出版

夢境 – 小學與營長

又作了一個詭異的夢~
地點像是以前的小學~
我好像為了一個很正當的原因遲到了,躲了起來~
我心裡很害怕,因為以往從來沒遲到過~
一直想跟老師說些什麼~卻又提不起勇氣~
後來
聯絡到我的好友
打算在某節課下課的時候混進去~~
但是在下課的時候
被老師抓到了~
老師當然責罵了一會,
我鼓起勇氣跟老師說明原因~
後來就被校長帶走
很奇怪的是
校長居然是我當兵時的康營長(還是蠻懷念這位營長的呢)~~
校長跟我談話,問明原因之後~
跟我要了家庭聯絡簿拿出來~
然後開始寫字~
接著告訴我”我會把聯絡簿交給你的導師,你先回去吧!”
===
沒了~~~

「天蠶變」讀後感

前幾天看到電視上有在上映「新天蠶變」,就想起童年時的「天蠶變」.
然後就想,這故事到底是什麼呀?作者又是誰呢??
於是心血來潮的利用 Google 去搜尋,居然被我找到了~~今天就偷偷利用上班的時間把它給看完了~~ ^_^
原來「天蠶變」的作者是黃鷹~內容還不錯~平舖直述的~也因此讓我能很迅速的瞭解雲飛揚為什麼在武當派被人冤枉,又為什麼學成絕世武功~~不過我個人認為要翻拍成對電視劇的話,就嫌不足了~
有很多的地方,作者都偷懶,並沒有詳述~很簡單的用文字把情節帶過去~我想可能是出版社或報社催促的緣故吧~~
結局挺出人意料的,幾乎所有人都死光光了~給人滄涼的感覺~~
呼~~~

CVS 簡易說明

我們先假設 192.168.0.1 有安裝 cvs server
並且有三個專案在上面
怎麼用??
0. 確定自己電腦上有安裝 cvs
一般來說,如果是 Red Hat 或 Mandrake,那麼預設會有安裝
如果是其他的,我就不知道了
請到 www.cvsroot.org 去下載套件並安裝之
1. 設定
#當然你如果習慣用 vi, 這邊的 EDITOR 就設為 vi 的路徑
export EDITOR=/usr/bin/vim
#此處的 username, 要替換為自己的 username
export CVSROOT=:pserver:username@192.168.0.1:/home/cvsroot
export CVSREAD=yes
你可以把這些敘述放到 /etc/profile 或 /root/.bash_profile 裡面
免得以後每次用的時候還要再打一次
2. login
輸入
cvs lgin
cvs 會要求你輸入密碼,此密碼就是你在 192.168.0.1 上的密碼
3. checkout 將專案下載到你的電腦上
所以你可以打
cvs checkout clockd
cvs checkout helloworld
cvs checkout qt
把專案下載到自己的電腦上
4.
做完 checkout 後,你可以看到自己的電腦上出現了專案
先輸入 cvs edit xxxx
然後就可以做編輯了,你可以試著亂改, 加上一些註解或無聊的程式碼
做完修改後,當然要放回 server 囉
你可以用
cvs commit [檔案名稱]
指令來更新回 server, 更新之前, cvs 會打開 editor 讓你輸入一些文字,為這次的修改作一些說明
對了,如果別人在你修改之前修改了這個檔案,那麼 cvs 會自動將檔案作合併,讓你再去做編輯,請務必玩一玩
5.
如果要看目前的狀況,就打
cvs status [檔案名稱]
cvs diff [檔案名稱]
cvs history [檔案名稱]
來查看各種狀況
6.
不想要這個檔案加入版本管理的話,得先刪除該檔案後,再使用
cvs remove [檔案名稱]
來移除
7.若要登出 cvs server,則輸入 cvs logout 即可

autofs 的應用

這是在這一期(2002/05)的 Linux Journal 看到的~~
以下是我的摘錄:
首先先假設你已經有了一堆 iso 檔案~
如果沒有
你可以用 cat /dev/cdrom > image1.iso 來建立 iso 檔案
要不然也可以利用免費的 iso buster 來建立 iso 檔案
再放到 Linux 上去
我們把這些 iso 檔案都放到 /mnt/images 下面
然後安裝 automount 套件~~
這個套件,CD 裡面應該就有附上了~
安裝以後,利用 chkconfig –list automount
確定 automount 會開機時自動啟動.
編輯 /etc/auto.master,
加上
/mnt/isosrv_auto /etc/auto.isorv –timeout=60
這表示 automount 會參考 /etc/auto.isorv 這個設定檔,自動掛載設定中的檔案系統到 /mnt/isosrv_auto 下
建立 /etc/auto.isorv
加上
image1 “tab” -fstype=iso9660,ro,loop “tab” :/mnt/images/redhat73_1.iso
上面這行的 表示要用 tab 分開(這是我自己實驗後的心得,automount 似乎會認格式)
image1 表示會在 /mnt/isosrv_auto 下建立的目錄名稱
-fstype=iso9660,ro,loop 表示檔案系統及參數
:/mnt/images/redhat73_1.iso 表示來源的所在位置
這樣設定之後
當你 ls /mnt/isosrv_auto/image1 的時候,linux 就會自動幫你掛載上去了
因為 ls /mnt/isosrv_auto 的時候,並沒有東西顯示,也因此無法得知有什麼目錄可以使用,此時可藉著 symbolic link 解決此問題
舉例來說,我們又另外建立 /mnt/CDs
然後在 /mnt/CDs 下建立 symbolic link 連結到 /mnt/isosrv_auto/image1
ln -s /mnt/isosrv_auto/image1 image1
這樣當你 ls /mnt/CDs 的時候
不就知道有什麼目錄了嗎?
套件的名字是叫做 autofs
後記:後來才知道除了 isofs 之外,這也能把一些其他的 filesystem 掛載進來,所以能應用的範圍就更廣囉.比如說可以配合 crond 用在自動備份上面,也是非常方便的呢. ^_^

cvsweb.cgi

前幾天, 友人找到一個不錯的 cvs web 介面,粉漂亮
是用 Perl 寫的CGI,於是我試著把他裝在 cvs server 上面~
一般的安裝方法,就是找到你的 httpd 伺服器,然後放在 cgi-bin/ 下面
以 redhat 為例,就是放在 /var/www/cgi-bin/ 下面
並且把執行的屬性改為執行~執行的擁有者改為適當的擁有者
但是在安裝以後
發現友人給我的檔案無法使用
於是我 follow 該檔裡面的網址前去下載~~
網址如下:
http://www.freebsd.org/cgi/cvsweb.cgi/www/en/cgi/cvsweb.cgi/
下載之後
發現仍然無法使用
他告訴我還需要
cgi-style.pl
我的老天,網海茫茫,到哪裡去找??
後來突然發現
http://www.freebsd.org/cgi/cvsweb.cgi/www/en/cgi/
這邊就可以看到 cgi-style.pl
下載之後
又發現我沒有 cvsweb.conf
於是再次從
http://www.freebsd.org/cgi/cvsweb.cgi/www/en/cgi/
找到 cvsweb.conf
這樣子,檔案就全部到齊了
請用編輯器打開 cvsweb.cgi, 找到以下這行
for (“$mydir/cvsweb.conf”, ‘/usr/local/etc/cvsweb/cvsweb.conf’) {
加入 /etc/cvsweb.conf,於是就變成
for (“$mydir/cvsweb.conf”, ‘/usr/local/etc/cvsweb/cvsweb.conf’,’/etc/cvsweb.conf’) {
然後再用編輯器打開 cvsweb.conf, 找到以下這行
@CVSrepositories = (
…….
);
這個 Perl 陣列裡面就是你的 CVS 存放的位置也就是 CVSROOT 所指的位置
請修改之以符合你的環境.
假設,你的 CVSROOT 是 /home/cvsroot/, 裡面有一個 respository 為 libs
那麼裡面就應該是
‘libs’ => [‘libs’, ‘/home/cvsroot’],
緊接著@CVSrepositories 下面,你會看到 %MIRRORS
如果你的 CVS Server 有 Mirror 的話
也請修改,否則的話,就把他清成空的,像是這樣~
%MIRRORS = (
);
修改之後,再打開瀏覽器去執行,果然看到 cvsweb 漂漂的畫面
一切就大功告成了~~
cvsweb.jpg

夢境 – 老師

那是專三或專四的時候
炎熱的下午
幾個同學趁著下課
跑去籃球場打籃球~
十分鐘哪夠他們打球呢~
很快就上課了
那堂是國文課~
我隔著窗子對著他們叫說”上課了!”
國文老師說:”由他們去吧~”
X X X
國文老師不繼續教我們了
那天是老師最後一天上我們的課
上完之後
我哭了
哭的很傷心,非常傷心
我已經很久沒有這樣子嚎啕大哭了~~
X X X
我發現我還在床上
臉上也沒有淚滴~
甚至我弟也沒被我的哭聲驚醒~
可是我的感覺是如此的真實~
罷了~~我繼續陷入半夢半醒~~
朦朧間
想起了教過我的幾位國文老師~~
國中的劉老師,林老師(應該沒記錯姓)
五專的陳老師(他正好跟某知名鋼琴音樂家同名同姓)~
真是非常謝謝他們
培養我欣賞詩文,國文的能力~
真的,非常謝謝他們~~
^_^

夢境 – 輪船,河岸與港口


今天早上又作夢了~~
有些地方已經忘記了~~
依照西藏羅桑倫巴喇嘛所說,夢境容易被遺忘,必須要經常訓練,才能記得~~
=====
眼前是一片寬廣的河岸~
橋橫亙在大河之上,連接兩岸~
天色像罩了一層霧似的~昏暗~
陽光試圖透進來,為昏暗添上了幾筆色彩.
輪船在靠近岸邊的地方沉了
我乘著小船在輪船附近
在岸邊
我看到一根鐵柱上
附著許多磁鐵
我一一拾起~~
=====
就這麼著
就這些~~
蠻不錯的小說開頭~
有點村上風
^_^

夢境 – 突圍

在一棟高樓裡
KYC, IS, 無名的人和我正在準備脫逃~
KYC: 當他們搭乘電梯下樓以後,我們就趁此機會,打開電梯鐵門,從鋼索滑下去~
IS,無名的人和我沒什麼意見,大家一致同意~
於是當他們搭乘電梯以後,我們就趕緊打開了電梯的鐵門
抓住了鋼索
慢慢往下滑
幸好電梯是往下的
這省了我們不少功夫
我們到了一樓
接著拼命往外逃
要到我們機車停放的地方~
就在快要到達停車處的時候
我們發現異狀
那兒有人在看守著
KYC決定往回走
IS決定去租車
無名的人決定打倒看守的人,和我的意圖不謀而合
商量一下之後
無名的人從正面
而我繞到看守人的後面去
我從巷子裡繞過去
快要出巷子的時候
我發現無名的人已經被發現,並被看守人抓住.
IS突然出現,她租到了機車,並且揚長而去.
我開始往巷子裡面走,想要趁亂逃走
可是想不到他們居然調動了軍隊
包圍了這附近
我低著頭
急步快行~~
=====
我醒來了~~
原來這是夢~~
=====
一如往常的搭乘機車上班
就在快要到公司的時候
車車的油線居然斷掉
讓我因此而無法催動油門
只好牽著車車
進到公司停車
突然
我發現到這或許就是夢所要告訴我的~

C++ 的 wstring

在 C 裡面有 wchar_t
那麼在 C++ 應當也有對應的 container 才對
經查訪之後
應該是 wstring

於是就寫了一個小程式來測試一下
[cpp]
#include <iostream>
#include <string>

int main(int argc, char* argv[] ) {
wstring ws;
ws=wstring(“This is a test”);
cout << ws << endl;
}[/cpp]
但卻遭遇編譯失敗.

在看過 C++ 的 header 之後
發覺他把 wstring 的部分給 remark 起來了
所以我利用 grep 去找尋相關的部分
並做了一些修正如下:

  1. 將 string 中的 wstring 前頭的註解拿掉
  2. std/straits.h 134行 #if 0 改為 #if 1
    std/cpp_type_traits.h 130行 #if 0 改為 #if 1
  3. 在 #include <string> 之前,要先
    定義 __USE_ISOC99 或 __USE_UNIX98 (但#define __USE_UNIX98 會使得 pthread 有誤)
    然後再 #include <cwchar> #include <cwctype>

結果呢
還是不行
真是傷腦筋~~

也許是因為雖然我用的是 gcc3 ,但header檔卻是 2.96 的緣故吧~