Recently, a website requires frequent use of remote data, and data interfaces are ready. During the conversion, I encountered a performance problem: I started to use PHP to implement the conversion. After several days of hard work, I did not find a method to directly operate on bytes. Although the Pack () method can be used to push data into the structure, unpack () cannot be used to extract the data.
// PHP code
For ($ I = 0; $ I <$ length; $ I + = 2 ){
$ Tempstr = $ tempstr. CHR (hexdec (substr ($ array ["data"], $ I, 2 )));
}
$ Array ["data"] = $ tempstr;
This method is used for decoding. Frequent use of various string operations will undoubtedly have a great impact on performance. After research, we found that the following methods can be used to perform operations on Bytes:
- Use stream for read/write
- Use SOCKET for read/write
- Use com DLL to convert data in C ++ DLL
Because no relevant documents can be found on the Internet (in fact it is not easy to find), stream and socket have been passed out. To compile the com DLL, we also downloaded VC ++ 6.0 (why not install 2005? Hard Disk is too small to fit. No way ). After the endless Google (all the DLL information written by PHP to call VB, not much help) and compilation/debugging, the results were finally successfully passed to PhP.
The following is a brief introduction.Steps and precautions:
- In VC ++ 6.0, choose file-> New..., select "atl com Appwizard" in projects, and enter the project name. In this example, the project name is "atltest ".
- In the "atl com Appwizard-Step 1 on 1" dialog box, select "dynamic link library (DLL)" for "server type" and finish.
- In "classview", right-click "atltest" and select "new ATL object... ", in" ATL object wizard ", select the default" Simple Object ", and then" Next ".
- In "ATL object wizard attribute", enter the interface name in "short name. In this example, the interface name is "test ". Then, the default values are automatically filled in for all textbox fields on the "names" tab. Note: One "prog ID" ("atltest. Test" in this example) and one "interface" ("itest" in this example ").
- After that, the "ctest" class is generated under "atltest classes" in "classview" and the "itest" interface is implemented.
- Right-click the "itest" interface and select "add method ...".
- In "add method to interface", enter the method name and parameters. Note: the return value must be hresult type. The actual return value is the last parameter. For example, // C ++ code
BSTR encode (unsigned int msgtype, unsigned int msglength, BSTR message)This function must be written
// C ++ code
Stdmethodimp ctest: encode (
Unsigned int msgtype,
Unsigned int msglength,
BSTR message,
BSTR * result
)This form. In addition, the returned values only accept simple types (do not know why, char ** cannot be used) and pointers, and BSTR cannot be used directly.
- Complete this function. Of course, for the sake of simplicity, a random value is assigned to the result to indicate that the parameter is successfully passed. No memory leakage issues were considered. // 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;
}
- Compile and register the obtained atltest. dll with regsvr32 before using COM for calling.
- Then write such PHP code: // PHP code
$ COM = new COM ("atltest. test") or die ("COM components cannot be created ");
$ Result = "unprocessed strings ";
Echo '$ result = "'. $ result. '" <br/> ';$ Result = $ com-> encode (1,1, "11 ");
Echo '$ result = "'. $ result. '" <br/> ';
$ COM = NULL;
- Note that "atltest. Test" is the "prog ID" in (4) just now, and the methods using encode () are different from those declared. It does not matter!
Of course, because three input parameters are not used at all, here and "11" are only used to satisfy the number of input parameters.
- What is the output of PHP? // Html result
$ Result = "unprocessed strings"
$ Result = "ASDFASDF"It can be seen that the $ result is successfully changed to the value assigned in the DLL, indicating that the value of the encode () method is successfully returned.
Several Questions
- Why is BSTR * returned in encode (), but in PHP, it becomes a string (BSTR? Is the automatic conversion performed by ATL or PHP?
- In the C ++ code, when will the space allocated for BSTR through sysallocstring () be garbage collected? Where is the collection responsibility? Will it cause memory leakage?
- After the evil C ++ 6.0 compiler, why does the returned value not support the simple type of char ** (using char ** to compile countless errors )? BSTR is essentially a pointer and does not support it (it indicates that only simple types and pointers are supported), so we have to use a nondescribedomainbstr. Well, next we will try to use ccombstr or _ bstr_t, which is better.
- Does sysfreestring () need to be used for processing the passed BSTR * result? In C ++, the release is undoubtedly required. But what does PHP do behind it? Is there any garbage collection for the unreferenced constant "unprocessed strings?
//////////////////////////////////////// //////////////////////////////////
PHP calls the DLL project using PHP. The idea of posting on the Forum is to use the dynamicwrapper method. Download dynamicwrapper. DLL to PhP ext and Windows system32, $ DW = new COM ("dynamicwrapper"); $ DW-> Register ("ebusbapi. DLL "," ebcreatedatafile ", 'I = sls'," F = s "," r = l "); $ CH = $ DW-> ebcreatedatafile (" 222 ", 11, "22"). In DLL, one of the functions is handle ebcreatedatafile (lpctstr lpfilename, DWORD dwcreationdisposition, and lpctstr lppassword). Expected result 0 is displayed. success /////////////////////////////////////// /// // 1. View CPU load:
Code:
<?php
$wmi = new COM('winmgmts://');
$processor = $wmi->ExecQuery("SELECT * FROM Win32_Processor");
foreach($processor as $obj){
$cpu_load_time = $obj->LoadPercentage;
}
echo $cpu_load_time;
?>
2. Call custom DLL components:
1) Create ActiveX dll component --
Code:
Public Function hello() As String
hello = "Hello World!"
End Function
Coexist as a "test. dll" File
2) register this component with regsvr32.exe
Regsvr32 test. dll
3) call this DLL component in PHP:
Code:
<? PHP
$ OBJ = new COM ("test. dll ");
$ Output = $ obj-> Hello (); // call the "Hello ()" method
Echo $ output; // display Hello world! (So this comes from the DLL !)
?>
/////////////////////////////////
Today, we will use the interface of the Industrial and Commercial Bank for an online payment. We will provide two DLL files and a description document, and an electronic certificate.
PHP calls the COM component. After searching for the COM component for a long time, I couldn't find a clear one. Is it too few or too simple to use this component?
No one writes.
What is com?
The COM (Component Object Model) Component Object Model is a way to share binary code across applications and languages. Yes
Objects located at the upper part of dce rpc point to the layer (associated service) to define public call agreements to allow code calls written in different languages,
And allow other language code to perform interactive operations (the previous question is that the Code is clearly understood by com). com can be loaded as a DLL by the local program or
To be called by a remote process through DCOM.
Preparations
For example, I made a COM component and created a VB6 project. ActiveX DLL named the project p_test and the class named c_test. The file content of the class is as follows:
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
If num> 0 then get_number_attrib = 1
If num = 0 then get_number_attrib = 0
End Function
Compile and generate the p_test.dll File
Step 1: As a COM component, the DLL must be reported to the system before it is identified by the system.
Regsvr32 [path]/[component file name]
Regsvr32 C:/Windows/system32/p_test.dll
Permissions are not prone to errors in the system folder system32.
At this time, the file cannot be moved. The system will find the file in this directory when using it. If you change the directory, you must delete the registration first.
Register again
Regsvr32/U [path]/[component file name]
The system displays a window indicating the operation is successful. The message indicates that the component dllregister is successful or the component dllunregister is successful.
The second step can be called directly.
<?
$ B = new COM ("p_test.c_test"); // generally, the front side is its main file name, followed by its class name. You can find this file from the registry.
Parts can be found
In this way, an object called B is generated, and we can use its attributes and methods to operate it.
$ A = $ B-> test_number (-454 );
Echo $;
?>
The possible problem is that when compiling the project
Microsoft Active Server Pages Object Library
Reference. Find and check the library for the specific implementation of "Project-> references.