項目中需要用DLL實現一些服務端的運算,故想到用COM來實現以下是在通過網上別人例子所做的總結:
- 在VC++ 6.0中,File -> New... 選擇Projects中的"ATL COM AppWizard",填寫工程名稱等。本例中,工程名為"ATLtest"。
- 在"ATL COM AppWizard - Step 1 on 1"對話方塊中,"Server Type" 選擇"Dynamic Link Library (DLL)",之後Finish。
- 在"ClassView"中,右擊"ATLtest",選擇"New ATL Object...",在"ATL Object Wizard"中,選擇預設的"Simple Object",之後"Next"。
- 在"ATL Object Wizard 屬性"中,在"Short Name"輸入介面的名稱。本例中,介面名稱為"test"。之後,"Names"選項卡中的所有textBox都自動填好了預設的值。注意兩個地方:一個"Prog ID"(本例中為"ATLtest.test"),一個"Interface"(本例中為"Itest")。
- 完成之後,在"ClassView"中,"ATLtest classes"下產生了"Ctest"類,並且實現了"Itest"介面。
- 右擊"Itest"介面,選擇"Add Method..."。
- 在"Add Method to Interface"中,填寫方法的名稱和參數。注意:傳回值一定是HRESULT型,真正的傳回值是最後一個參數。比如//C++ code
BSTR Encode(unsigned int msgType, unsigned int msgLength, BSTR message)這個函數,要寫成
//C++ code
STDMETHODIMP Ctest::Encode(
unsigned int msgType,
unsigned int msgLength,
BSTR message,
BSTR *result
)這樣的形式。還有就是傳回值只接受簡單的類型(不知道為什麼,char**不能用)和指標,BSTR沒法直接使用。
- 完成這個函數。當然,為了簡單起見,這裡就是給結果隨便賦了一個值,用來說明參數成功的傳遞出來了。沒有考慮任何記憶體流失問題。//C++ code
STDMETHODIMP Ctest::Encode(
unsigned int msgType,
unsigned int msgLength,
BSTR message,
BSTR *result
)
{
BSTR temp = ::SysAllocString(L"asdfasdf");
*result = temp; return S_OK;
}
- 編譯,將得到的ATLtest.dll使用regsvr32進行註冊,註冊命令:regsvr32 ****.dll 卸載命令:regsvr32 ****.dll /u/s
- 之後書寫這樣的php代碼://php code
$com = new COM("ATLtest.test") or die("無法建立COM組件");
$result = "未處理的字串";
echo '$result = "'.$result.'"<br />';$result = $com->Encode(1,1,"11");
echo '$result = "'.$result.'"<br />';
$com = null;
- 注意這裡的"ATLtest.test"是剛才(4)中的"Prog ID",並且使用Encode() 的方法和聲明的也不一樣。沒有關係!
當然,由於完全沒有用到三個輸入參數,這裡的1,1,"11"只是為了滿足輸入參數的數量。
- 這個php的輸出是什麼樣的呢?//HTML 結果
$result = "未處理的字串"
$result = "asdfasdf";//我在這裡實驗沒有成功,輸出的是result="";但是函數確實已經執行,可能是由於php與ATL參數匹配的問題?我這裡沒有用到傳回值,所以就先這樣了,如果誰知道原因或解決辦法,請不吝賜教啊