COM component design and application 3 - Data type

xiaoxiao2021-03-18  268

Function Return Value Return Value Information Double Sin (Double) Floating Point Numerical Calculation Positive Mysterious Bool Deletefile (LPCTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSUED SUM DATE File Delete Success. If you fail, getLastError () can get a failure reason void * malloc (size_t) memory pointer memory application, if you fail, return the null nulllong regdeletekey (HKEY, LPCTSTSTR) integer to delete the registry key. 0 Successfully, non-0 failed, and this value reflects the cause of the failure of the uint dragqueryfile (HDROP, UINT, LPTSTR, and UINT) integer acquires drag and drop file information. Take different parameters, return different meanings: I will represent the number of files for a while, and I will represent the length of the file in a while. ..... so complicated return value, so that you have changed the return value, which makes everyone add additional difficulties in learning and use. Ok, COM design specification is finally unified. In addition to iUnknown :: addRef () and iUnknown :: addRef () and iunknown :: exese () and iunknown :: release (), all other functions are used as the return value as the HRESULT. Everyone imagines that the interface function of a component is called add (), completes 2 integers, in the C language, we can define as follows: long add (long N1, long n2)

{

RETURN N1 N2;

} Remember the principle we said just now? The COM component is running in a distributed environment. That is, this function may run on the "other side of the earth", since it runs so far, there may be a server shutdown, network drop, run timeout, the other party is not in the service area ... Waiting for an exception. Thus, this addition function should return a value in addition to the need to return the calculation result ------ The function is executed normally. HRESULT ADD (long N1, long N2, long * psum)

{

* psum = n1 n2;

Return S_OK;

} If the function is executed normally, return S_OK, and the real function runs the result back through the parameter pointer. If an abnormal situation is encountered, the COM system is judged, and the corresponding error value is returned. Common return values ​​are:

HRESULT value Meaning S_OK0x00000000 success S_FALSE0x00000001 function successfully executed, but the error parameter error E_INVALIDARG0x80070057 error E_OUTOFMEMORY0x8007000E memory allocation error E_UNEXPECTED0x8000FFFF unknown exception E_NOTIMPL0x80004001 unrealized function E_FAIL0x80004005 no details of when to return. Invalid typically needs to obtain Rich Error error information (Note 1) E_POINTER0x80004003 handles invalid pointer E_HANDLE0x80070006 E_ABORT0x80004004 terminating operation E_ACCESSDENIED0x80070005 access denied E_NOINTERFACE0x80004002 not support interfaces view of a structure HRESULT HRESULT is actually a two-byte value, which is the most significant bit ( Bit) If 0 is successful, 1 means an error. See the "Structure of Com Error CODES" in MSDN. If we need to judge the return value in the program, we can use the comparison operation symbol; Switch switch statement; you can also use the macro provided by the VC: HRESULT HR = Call Component Function; if (succeededed (HR)) {...} // If successful

......

IF (Failed (HR)) {...} // If the failed

... Third, after the Unicode Computer Invention, in order to represent characters in the computer, people have developed a code called ASCII. The ASCII code is represented by 7 bits (bits) in one byte, and the range is 0x00 - 0x7f with a total of 128 characters. They thought that these 128 numbers were enough to represent Abcd .... Abcd .... 1234 these characters. Cough ... people who speak English are "stupid"! Later, they suddenly found that "Table" is missing if they need to print these characters in form. Therefore, the definition of ASCII is expanded, using all of the 8-bit (bit) of one byte to represent characters, which is called the ASCII code. The range is 0x00 - 0xFF with a total of 256 characters. Cough ... people who speak Chinese are smart! Chinese people use a continuous 2 extended ASCII code extended area (after 0xA0) to represent a Chinese character, the standard is called GB-2312. Later, Japanese, Korean, Arabic, Taiwan Traditional (BIG-5) ... all expand the definition of local character sets using a similar approach, and now collectively referred to as MBCS character set (multi-byte character set). This method is defective because the character set defined in each country has an intersection, so the software using GB-2312 cannot run in the BIG-5 environment, and vice versa. Cough ... people who speak English finally changed "smart". In order to unify all the words symbols all of the world people, the Unicode standard character set is developed. Unicode uses two bytes to represent a character (unsigned shor int, wchar, _wchar_t, olechar). This is finally good, the software in any region around the world can run in another region without modifying. Although I browsed the Japanese website with IE, I showed the Japanese text I didn't know, but at least it would not be garbled. The range of Unicode is 0x0000 - 0xffff for a total of more than 60,000 characters, with light Chinese characters take up more than 40,000. Hey, Chinese people earn Dafa: 0) Use various character sets in the program: const char * p = "hello"; // use ASCII character set

const char * p = "Hello"; // Using the MBCS character set, because MBCS is fully compatible with ASCII, in most cases, we don't strictly distinguish between them LPCSTR P = "Hello, hello"; // Significise

Const Wchar * P = L "Hello, Hello"; // Use Unicode Character Set

LPColestr P = l "Hello, Hello"; // Significise

// If you predefined _unicode, you will use the Unicode character set; if _mbcs are defined, it means using MBCS.

Const tchar * p = _t ("Hello, Hello");

LPCTSTR P = _t ("Hello, Hello"); // Significantly in the above example, T is a very interesting symbol (tchar, lpctstr, lptstr, _t (), _ text () ...), it Indicates that uses a middle type, which is neither explicitly representing the use of MBCs, nor explicitly represents Unicode. Which character set is it used? Hey ... Decide when compiling. To set the condition: VC6, "Project / Settings ... / C / C card preducessor definitions" Add or modified _mbcs, _unicode; vc.net, project / property / configuration properties / regular / characters Set "then select with a combination window. Use T type, is a non-good habit, seriously recommended! 4. In addition to the use of some simple standard data types (Note 2), the string type needs to be specifically focusmed. Remember the principle? The COM component is running in a distributed environment. It is popular that you can't pass a memory pointer directly to the COM function directly as a parameter. You think that the system needs to pass the contents of this memory to the computer of the "Earth", so I at least need to know the size of your memory? Otherway, how can I pass? How many bytes are delivered? ! The string is also a type of very commonly used, so the COM designer introduces the representation of the string type in Basic --- BSTR. BSTR is actually a pointer type, its memory structure is: (input program fragment BSTR P = :: sysallocstring (l "hello, hello"); breakpoint execution, then observe the memory of P, BSTR memory structure BSTR It is a pointer to the Unicode string, and in the 4 bytes of BSTR, the byte length of this string is saved with DWORD (not ending the string). Therefore, the system can handle and transmit this string to "the other side of the earth". It is particularly important to note that since the pointer of the BSTR is point to the Unicode string, BSTR and LPoLESTR can be mixed to a certain extent, but must pay attention to: there is a function FUN (LPColestr LP), you call BSTR P = ...; Fun (p); correct function fun (const bstr bstr), you call lpcolestr p = ...; fun (p); error! ! ! Processing function about BSTR:

API function Description SysallocString () Apply for a BSTR pointer and initials to a string sysfreestring () release BSTR memory sysallocstringlen () to apply for a BSTR pointer to specify the length of the character, and initialize a string sysallocstringBytelen () to apply for a specified byte length BSTR pointer, and initialized to a string sysReallocStringlen () Reselection BSTR pointer cstring function Description AllocSystring () gets BSTRSTSTRING () from CString to the BSTR pointer and copy to CCOMBSTR function ATL's BSTR package class in CSTRING. Defining append (), appendbstr (), Appendbytes (), Appendbytes (), APPENTOARRAY (), ASSIGN, COPYTO Length (), bytelength (), readfromstream (), WritetStream (), LoadString (), TOLOWER (), TouPper () operator overload:!,! = ==, <,>, &, =, , = BSTR is too much, but from the function name cannot see its basic functions. Details, view msdn. In addition, the left function, there are many of the ATL 7.0 provided, and the ATL 3.0 belled under VC6.0 does not support. Since we will use ATL development component programs in the future, use ATL's CCOMBSTR. The VC also provides other packaging classes_bstr_t. V. Conversion between various string types 1. Function widechartomultibyte (), convert Unicode to MBCS. Example: lpcolestr lpw = l "Hello, Hello"; size_t wlen = WCSLEN (LPW) 1; // Wide character character length, 1 indicates that the string end value

INT alen = WideChartomultibyte (// First call, calculate the required MBCS string byte length

CP_ACP,

0,

LPW, // wide string pointer

Wlen, // character length

NULL,

0, // Parameter 0 Indicates the character space after the conversion

NULL,

NULL);

LPSTR LPA = New Char [alen];

WideChartomultibyte

CP_ACP,

0,

LPW,

Wlen,

LPA, // Converted string pointer

Alen, / / ​​give a space size

NULL,

NULL);

// At this time, the converted MBCS string is saved in the LPA.

... ...

DELETE [] LPA; 2, function multibytetowideChar (), convert MBCS to Unicode. Example: lpcstr lpa = "Hello, Hello";

SIZE_T alen = Strlen (LPA) 1;

Int Wlen = MultibyToWideChar (

CP_ACP,

0,

LPA,

Alen,

NULL,

0);

LPolestr LPW = New Wchar [WLEN];

MultibyToWideChar (

CP_ACP,

0,

LPA,

Alen,

LPW,

Wlen);

... delete [] lpw; 3, using the converted macro provided by ATL.

A2BSTROLE2AT2AW2AA2COLEOLE2BSTRT2BSTRW2BSTRA2CTOLE2CAT2CAW2CAA2CWOLE2CTT2COLEW2COLEA2OLEOLE2CWT2CWW2CTA2TOLE2TT2WW2ELEA2WOLE2WT2WW2T

The macro function in the above table is actually very easy to memorize:

2 Good funny abbreviation, TO pronunciation and 2, so borrowed to represent the meaning of "converted to, transition to". Aansi string, that is, MBCS. W, ole wide string, that is, Unicode. T Intermediate Type T. If the _unicode is defined, then t represents W; if _mbcs are defined, T represents the abbreviation example of AcconSt: #include

Void fun ()

{

Uses_conversion; // only needs to call once, you can perform multiple conversions in the function.

LPCTSTR LP = OLE2CT (l "Hello, Hello"));

... ...

// Don't explicitly release the memory of LP, because

// Since the ATL conversion macro uses the stack as a temporary space, the stack space is automatically released after the function is completed.

} Using the ATL conversion macro, it is very convenient to use it without freeing the temporary space. However, take into account the size of the stack space (VC default 2M), pay attention to a few points when using: 1, only suitable for short-string conversion; Trying to convert the contents of the character file, because the file size is generally large; 4, on the case 2 and 3, to use multibytetowidechar () and widechartomultibyte (); 6, Variant C , Basic, Java, Pascal, Script ...... The computer language is diverse, and they have their own data types, COM generate, one is to cross the language (Note 3). The Variant data type has a cross-language characteristic, and it can represent (store) any type of data. From the perspective of C language, Variant is actually a structure, which is represented by a domain (VT) in the structure ------ This variable indicates what type of data is represented, and the real data is stored in Union space. . The definition of the structure is too long (although long, but in fact, it is very simple) Let's go to MSDN's description, here is a simple example of how to use: Student: I want to express a 4-byte long integer with Variant, how to do? Teacher: Variant V; v.vt = vt_i4; v.lval = 100; Student: I want to use Variant to express the Boolean value "true", how to do it? Teacher: Variant V; v.vt = vt_bool; v.boolval = variant_true; student: Is this trouble? Can I can't v.Boolval = True; write this? Teacher: No! because

Type Byte Length Value Value Bool1 (CHAR) 0 (FALSE) 1 (TRUE) Bool4 (INT) 1 (TRUE) VT_BOOL2 (variant_false) -1 (variant_true) So if you v .boolval = true assigns this, then the problem will be issued when IF (Variant_true == V.BOOLVAL) (-1! = 1). But you pay attention to observation, any "false" of any Boolean type is 0, so as a good habit, when doing Boolean judgment, don't compare with the "true value", and to compare with "false value". Student: Thank you teacher, you are too big. My respect for the teacher is like a river, which is endless ... Student: I want to save strings with Variant, how to do it? Teacher: Variant V; v.vt = vt_bstr; v.bstrval = sysallocstring (l "Hello, Hello"); Student: Oh ... I understand. But this is really troublesome, is there a simple way? Teacher: Yes, you can use ready-made packaging ccomvariant, Colevariant, _variant_t. For example, three questions above can be written like this: CCOMVARIANT V1 (100), V2 (True), V3 ("Hello, Hello"); simple? ! (Note 4) Students: Teacher, I will ask the last question, how do I save an array with Variant? Teacher: This problem is very complicated, I can't tell you now, I now tell you that you are not impressed ... (Note 5) Students: ~! @ # $% ^ & * () ..... .gosh! Seven, the content described above is the basic skill, must be skilled. Let's get here, take a break ... More exciting content, please pay attention to "COM component design and application (4)" Note 1: Introduced in subsequent iSupp PorterRorInfo interface. Note 2: Common data types, please refer to the IDL file. (Don't worry, haven't written it ... 嘿) Note 3: Cross language is the use of COM components in various languages. But can I cross the platform? Note 4: Ccomvariant / Colevariant / _variant_t, please see MSDN. Note 5: The use of safe array SafeArray is discussed in subsequent articles.

I. Introduction

The goen back book introduces the concept of GUID, CLSID, IID, and interface. The focus of this back is to introduce the data type in COM. Don't you introduce the design steps of the component program? Cough ... Don't worry, don't worry! Confucius said: "The rice must be eaten in a silend"; Lao Diao: "I can't eat hot tofu", Sun Ziyun: "Take a step" ... first master the necessary knowledge, write the procedure in the future I will have my heart :-)

Before walking into the topic, please remember a principle:

The COM component is running in a distributed environment. For example, you write a component program (DLL or EXE), then the user may be loaded with the component (Inproc_server) in a certain process of this machine; or the process of calling the component from another process (local_server); It may be that the component (Remote_Server) on the computer on the computer is called on this computer. So when you understand and design, you will always think of this sentence. fast! Take a small book, write down! Second, the HRESULT function return value

Everyone has their respective philosophical ideas when they are designed. There are many forms of forms of the function return value.

转载请注明原文地址:https://www.9cbs.com/read-129936.html

New Post(0)