php調用com

來源:互聯網
上載者:User

標籤:std   sls   result   sig   china   通過   hello   var   view   

轉載自http://blog.chinaunix.net/uid-20787846-id-3530180.html

編譯com的dll

下面簡單介紹一下步驟和注意事項:

  1. 在VC++ 6.0中,File -> New... 選擇Projects中的"ATL COM AppWizard",填寫工程名稱等。本例中,工程名為"ATLtest"。
  2. 在"ATL COM AppWizard - Step 1 on 1"對話方塊中,"Server Type" 選擇"Dynamic Link Library (DLL)",之後Finish。
  3. 在"ClassView"中,右擊"ATLtest",選擇"New ATL Object...",在"ATL Object Wizard"中,選擇預設的"Simple Object",之後"Next"。
  4. 在"ATL Object Wizard 屬性"中,在"Short Name"輸入介面的名稱。本例中,介面名稱為"test"。之後,"Names"選項卡中的所有textBox都自動填好了預設的值。注意兩個地方:一個"Prog ID"(本例中為"ATLtest.test"),一個"Interface"(本例中為"Itest")。
  5. 完成之後,在"ClassView"中,"ATLtest classes"下產生了"Ctest"類,並且實現了"Itest"介面。
  6. 右擊"Itest"介面,選擇"Add Method..."。
  7. 在"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沒法直接使用。
  8. 完成這個函數。當然,為了簡單起見,這裡就是給結果隨便賦了一個值,用來說明參數成功的傳遞出來了。沒有考慮任何記憶體流失問題。

    //C++ code
    STDMETHODIMP Ctest::Encode(
        unsigned int msgType, 
        unsigned int msgLength, 
    BSTR message, 
    BSTR *result
    )
    {
    BSTR temp = ::SysAllocString(L"asdfasdf");
        *result = temp;

    returnS_OK;
    }
  9. 編譯,將得到的ATLtest.dll使用regsvr32進行註冊,之後才能使用COM進行調用。
  10. 之後書寫這樣的php代碼://php code 
    $com = new COM("ATLtest.test") ordie("無法建立COM組件");
    $result = "未處理的字串";
    echo‘$result = "‘.$result.‘"
    ‘;

    $result = $com->Encode(1,1,"11");
    echo‘$result = "‘.$result.‘"
    ‘;

    $com = null;
  11. 注意這裡的"ATLtest.test"是剛才(4)中的"Prog ID",並且使用Encode() 的方法和聲明的也不一樣。沒有關係!
    當然,由於完全沒有用到三個輸入參數,這裡的1,1,"11"只是為了滿足輸入參數的數量。
  12. 這個php的輸出是什麼樣的呢?

    //HTML 結果 
    $result = "未處理的字串"
    $result = "asdfasdf"
    可見,$result 成功的改變成了dll中賦的值,說明 Encode() 方法成功的返回了值。

幾點疑問

    1. 為什麼 Encode() 中返回的是 BSTR* ,但是到了php中,就變成了字串(BSTR) 呢?這個自動的轉換是ATL進行的,還是php進行的呢?
    2. C++代碼中通過SysAllocString()為BSTR分配的空間在何時進行垃圾收集?收集工作由哪裡負責?會不會導致記憶體流失?
    3. 完惡的C++ 6.0 編譯器,為什麼傳回值不支援 char** 這種簡單的類型呢(使用char**直接編譯出無數錯誤)? BSTR本質上就是指標嘛,也不支援(提示說只支援簡單類型和指標),只好用一個不倫不類的BSTR*來寫。嗯,下一步嘗試改用CCOMBSTR或者_bstr_t,試試哪個更好用。
    4. 對於傳入的BSTR* result,需要使用 SysFreeString() 進行處理嗎?在C++中看來,無疑是需要釋放的;但是php在背後做了哪些工作呢?有沒有對未被引用的常量"未處理的字串"進行垃圾收集呢?

PHP調用dll

用DynamicWrapper方法調用。下載DynamicWrapper.dll到php ext下與windows system32下

$dw = new COM("DynamicWrapper"); $dw->Register("EbUsbApi.dll", "EbCreateDataFile", ‘i=sls‘, "f=s", "r=l"); $ch = $dw->EbCreateDataFile("222",11,"22"); #dll其中一個函數 HANDLE EbCreateDataFile(LPCTSTR lpFileName, DWORD dwCreationDisposition, LPCTSTR lpPassword) 

查看CPU荷載:

$wmi = new COM(‘winmgmts://‘);$processor = $wmi->ExecQuery("SELECT * FROM Win32_Processor");foreach($processor as $obj){    $cpu_load_time = $obj->LoadPercentage;}echo $cpu_load_time;

調用自定的dll組件:
1) 建立ActiveX dll組件 --

CODE:

Public Function hello() As String
    hello = "Hello World!"
End Function並存為"test.dll" 檔案

2) 用regsvr32.exe註冊此組件
regsvr32 test.dll 

3) 在PHP內調用此dll組件:

$obj = new COM("test.dll");$output=$obj->hello(); // Call the "hello()" 方法echo $output; // 顯示Hello World! (so this comes from the dll!)

準備工作

比如我作了一個COM組件,建立一個VB6工程,ActiveX Dll將工程命名為P_test,類名為c_test ,類的檔案內容如下:

Option Explicit
Private MyScriptingContext As ScriptingContext 
Private MyApplication As Application
Private MyRequest As Request Private MyResponse As Response
Private MyServer As Server 
Private MySession As Session Public

Sub OnStartPage(PassedScriptingContext As ScriptingContext) 
Set MyScriptingContext = PassedScriptingContext 
Set MyApplication = MyScriptingContext.Application 
Set MyRequest = MyScriptingContext.Request 
Set MyResponse = MyScriptingContext.Response 
Set MyServer = MyScriptingContext.Server 
Set MySession = MyScriptingContext.Session 
End Sub

Public Sub OnEndPage() 
Set MyScriptingContext = Nothing
Set MyApplication = Nothing
Set MyRequest = Nothing 
Set MyResponse = Nothing 
Set MyServer = Nothing 
Set MySession = Nothing 
End Sub

Public Function Test_Number(num) As Variant 
If num < 0 Then Get_Number_Attrib ="-1" br style=‘font-size:16px;font-style:normal;font-weight:400;font-family:Verdana;color:rgb(102, 102, 102);‘ />If num > 0 Then Get_Number_Attrib = 1 
If num = 0 Then Get_Number_Attrib = 0 
End Function

編譯產生p_test.dll檔案 

第一步,做為一個COM組件,這個DLL要被系統識別就要先到系統來報到

   regsvr32 [路徑]/[組件檔案名稱]

   regsvr32 C:/WINDOWS/system32/p_test.dll   
   放在系統檔案夾system32下不容易出現許可權問題

這時候這個檔案就不能移動位置了,系統會在用到它時到這個目錄來找,如果改目錄就得先刪除註冊

再重新註冊

   regsvr32 /u [路徑]/[組件檔案名稱]

系統會顯示視窗表示成功,大意是 組件Dllregister成功或是Dllunregister成功


第二步就可以直接調用它了

$b=new COM("p_test.c_test");  //一般前邊是它的主檔案名後邊是它的類名從註冊表裡找這個檔案可以找到。這樣就產生了一個叫b的對象,我們就可以用它的屬性和方法來操作了$a=$b->Test_Number(-454); echo $a; 

可能遇到的問題是,編譯工程時通不過,要將 
Microsoft Active Server Pages Object Library  
引用進來,具體實現"Project->References"找到改庫,並勾上 。

php調用com

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.