"I really can't think of the series. After many this kind of emotion, I found that as long as we move your brains, we can have something that I can't think of others. So I thought that I would like to share these things and share it with everyone, I hope to throw bricks to introduce more people who can't think about it.
I really can't think of one of the series: What did VB do for us? Keywords: VB, underlying, Win32, API, COM difficulty: Intermediate requirements: familiar with VB, use VC debuggers to learn about Win32 SDK, COM. VB has always been considered to have the following advantages and disadvantages: the advantage is fast, high development efficiency; the disadvantage is limited, and the operating efficiency is low. This is exactly some software as the preferred language, and some software will definitely do the reason for VB. And many VCs, Delphi's programmers believe that VB is unfair in VB, which makes us easy to make things easier, and let us play more and smaller. Indeed, the simple and powerful, the two itself is a pair of contradictions. It's afraid of a line of code, just start running an empty form, which is simple to operate, and the VB will make a lot of complex work for us (it is not just the registration window, the display window, the start message loop is so simple), these Work is transparent to programmers. We are grateful to the VB Development Team to attach the programs to the micro-micro, and you can't help but blame why the action only in the document is not mentioned. Although these actions may have no effect on the final procedure, we have the right to know What's more, these actions sometimes affect our work (I will talk about this impact in the "VB multi-thread" behind this series). However, all the friends who wish to get "unapproved technology secrets" from this article will be very disappointed, because I can know the same as you, everything we can do is to stand outside to guess VB, what did you do? So I must never take everyone to go to the VB reverse engineering, but want to make some primary blurred concepts through the interior of the VB. As a series of first articles, its purpose is to make the foundation in the back of the back, so I will point out the knowledge points we must master when I need it. If you don't know, please study the relevant books in time to make up the class, specifically See "Reference Book". Finally, we must declare that all kinds of experiments and invested in this article are only my personal point of view, and they cannot guarantee their correctness and do not assume any relevant legal responsibilities. Ok, start! First prepare our weapons, I have the tools you need to use Mainly: VB6 Chinese Enterprise Edition SP5 (nonsense), SPY , Dependency Walk and Ole Viewer (hereinafter referred to as SPY and Depend and Oleview, SPY CommON in VB CD) In the SPY directory in / Tools / VB /, OleView is OLEVIEW.EXE in the Oletools directory, pay attention to it. There is also an OLE2VW32.exe function, but this article refers to Oleview.exe, but also Denpend Unsupprt / dependend). Also use VC (the tool mentioned above in VC), because we also have to look at the code generated by VB, engage in VB senior development, you must use the VC debugger, understand the compilation better. Of course, the focus of this article is not here, so there is no VC to be tight. Open the VB6 new standard EXE project, in the Project -> References dialog, you should have four references, simple points are: 1, Visual Basic for Application (VBA) 2, VB Runtime Object Library 3, VB Object Library 4, OLE Automation. The first three are any VB projects, you don't want it, don't believe you try to remove them.
Then there is what role in these three core type libraries, what role is played in the final generated executable, which is the first question to analyze this article. 1) VB, VBA, VBS distinguishment, is you clear? First of all, VBS should not be compared to VB, VBA, which is Microsoft's scripting language that is started with the first ActiveX Scripting specification, although its grammatical structure and VB are very similar, but VBS only rely on automation objects to expand its Function (only later binding), it cannot be implemented with IMPLEMENTS, it is impossible to use the API directly in the VBS, and there is no Varptr to get a function of the pointer, and these functions that VBS miss are all unique to VB and VBA. Of course, this is not said that VBS is not as VB or VBA. Windows has provided a strong feature for VBS. We can use VBS to do script COM components, and the ability of the automation object can say unlimited, so there is viral VBS Write, the most important feature of the programmer VBS is to provide macro functions to our software, just like the VBS macro function provided in the VC. Note that VBS is free, this and the use of VBA in Office to provide a macro function, to integrate VBA requires no low price license fees, and see the scripting language Platform SDK / Tools and Languages / Scripting. (In this series, "Script Function" I will do a small software with VBS to provide a macro function) So what is the difference between VB and VBA? Ok, see it is true, start our experiment! If you install Office 2000 or more, open OleView, click on the View Typelib to view the VBE6.DLL of the E: / Program Files / Common Files / Microsoft Shared / VBA / VBA6, and use the same method to see Look at the type library of msvbvm60.dll, you will find that their type library is basically exactly the same, in addition to VBE6 more Vbeglobal interface and implementing this interface of the global object, this Global object we can also program the environment in the VBA (like Word VB) Editor) See the object browser. It has two methods to LOAD and UNLOAD, as well as a UserForms property, because VBA6 uses the MS Form 2.0 Form Designer (FM20.dll) to design and use the Userform form (in VB6, we can use multiple design For example, by using the MS Form 2.0 Form designer, we can use the USERFORM user form used by VBA in VB. Similar to the VBA's Global object, there is also a Global object in VB. From the VB object browser, you can know that it is in VB6.OLB type library, this type library is the VB object library that must be referenced in each project, all The VB built-in object is here. The objects used in the VBA's Userform are in FM20.dll. In addition to the above different, VB and VBA have a biggest difference, that is, VBA cannot generate an Exe executable, but can guess VBA and VB in the IDE environment to be compiled into P-code to execute, and I will use it later. Experiments have proven to be in this way, although VB and VBA are very different in specific implementations. From the above analysis, VB and VBA can be seen very different, which is mainly reflected in the programming environment and object structure, but in essence, there is a non-cut blood source relationship.
If you just carefully observe the type library of msvbvm60.dll, you will find the following piece: // generated .idl file (by the ole / com object viewer) [DLLNAME ("VBA6.DLL"), UUID (35BFBDA0 -2BCC-1069-82D5-00DD010EDFAA), helpcontext (0x000f6ec4)] module Strings {[entry (0x60000000), helpcontext (0x000f665f)] short _stdcall Asc ([in] BSTR String); [entry (0x60000001), helpcontext (0x000f6e9f) ] Bstr_stdcall _b_str_chr ([in] long charcode; .............} What? Objects in msvbvm60.dll have their methods defined in VBA6.DLL? ! Don't you have a vba6.dll in the VB installation directory? Use oleView to see it, wow thiophene, I really can't think of it actually exactly the same as MSVBVM60.DLL. what happened? Hurry up with DEPEND to see the output functions of the three DLLs of VBA6.DLL, MSVBVM60.DLL and VBE6.DLL. Ha, there is a new discovery, we can find that most of the two DLL output functions are one of the most models of the RTC, such as RTCMSGBOX (RTC, what? Should be Run Time? Component? Control? Code? Does anyone know?), This shows that the three DLLs have the same runtime VBA function. We can use Depend to observe VB6.exe, we can find that vb6.exe introduces some of the functionality that it unique to EB and TIP in VBA6.DLL, from these functions, you can find that their features are identical For example, the 79 EBSHOWCODE and 82 TipdeleTemodule. Vb6.exe does not have a function that is incorporated into any RTC (note one). Let's take a look at MSVBVM60.dll, just find a compiled file with the msgbox function, use Depend to observe it, it will find it to introduce the 595 RTCMSGBox function output by MSVBVM60.DLL (Note 2). And introduce a lot of functions in MSVBVM60.DLL, such as __vbavarabs (notice 3). In fact, from this three "attention" we can have some conjecture, no matter whether it is wrong, you can think about it. If you don't follow me to do experiments, but just watch this article, I guess you should be a bit fainted. If you do these experiments yourself, now you should be full of questions, and you should see the conclusion. So please tried to try it in hand, learning research issues are more important than reading conclusions. At least we can conclude: VB and VBA this is the same as the sisters, but the sister VB is better than the sister VBA. However, my sister will only sing a businessman; my sister will only be big.
My sister has a fertility, it is a real woman; the sister will not be born, but they deeply spectrum. Some teaching command can make her husband a lot, while VBS, it is also a daughter of everyone. No VB and VBA sisters excellent bloodline, Jiao Xiaolong must not roughly swear some automatic obedience to work, she is happy to help people like VBA, VB, VBA, VBS three women I like.
2) What did Native Code do? Take a spirit, let's go deep into step. The type library obtained with OLEVIEW does not correctly reflect the function portfolio in the DLL corresponding to each object method. You should have found that the Entry property value of each method in the IDL file obtained with oleView is 0x600000xx. To get the true portal in the type library in the DLL, we need to write the program yourself. Even in VB, we can also get very easy to obtain type library information, plus point COM initialization and calling code, we can use your code to implement the CallByName function introduced by VB6 ("HACK COM" behind this series I will talk more about COM, which is very important to the understanding of COM as a VB programmer). Since the key to this article is not to guide how to use the type library in VB, the method provided below is simple as possible. Create a standard EXE project, add a reference to TypeLib Infomation, put a label called lblinfo in Form, then add the following code: 'Program 1Private Sub Form_Load () Dim Otlinfo As Typelibinfo Dim OMEMINFO As MemberInfo Dim Sdllname As String Dim Sordinal As Integer Set oTLInfo = TLI.TypeLibInfoFromFile ( "MSVBVM60.DLL") lblInfo = "MATH module includes the following methods:" & vbCrLf For Each oMemInfo In oTLInfo.TypeInfos.NamedItem ( "Math") Members With oMemInfo .GetDllEntry sDllName, vbNullString. Sordinal lblinfo = lblinfo & .name _ & "Defines in" & SDLLNAME & "," _ & "It is" & sordinal _ & vbcrf end with next after running, we can know the ABS method definition in the MATH module. In VBA6.DLL, it is numbered 656. Viewing the function numbered 656 in VBA6.dll in Depend, it is RTCABSVAR, try the same as VBE6.DLL. I still remember the attention of the previous, VB6.exe does not introduce the RTC start function This means that the VBA method implemented in the IDE environment is actually the method in the VBA object library in the IDE environment (tracking P-Code is a nightmare, so I can't Verify what binding method it uses). Note In the final executable program mentioned in the second, RTCMSGBOX is introduced. If the final program we expect will call it directly, it is more than COM call, but when tracking the final procedure, I found that RTCMSGBOX is passing through After 205,000 miles, it will only call Messageboxa this API, there are many COM calls to other objects, slow! It may be because it is displayed in the modal dialog, there are many factors that need to be considered in multi-process multithreaded environments. If you are a crazy programs, you should try to override MSGBOX with API, absolutely a lot.
Let's take a look at it. Let's compile the following programs into "program 2.exe" using local code (for later experiments, you can set it "no optimized" and "generation in the engineering property of the engineering attribute." Symbolization debug information "program 2.exe" ": 'Program 2Private Declare Sub debugbreak lib" kernel32 "() private sub main () DIM I as long, j is long Dim K i = & h1234 debugbreak k = 1234 j = ABS (k) J = ABS (i) MsgBox "SS" J = Varptr (i) End Sub with depend observation "program 2.exe", we can find "program 2.exe" does not introduce 595 as we expected The RTCMSGBox introduces 656 RTCABSVAR. In the contrary, it introduces __vbavarabs and __vbai4abs, and look at the function name to know that a tar is Variant, a Forning is long. This shows that VB can further process the object ABS in the finally generated code, and observe that all the most commonly used VBA functions are mostly the most commonly used VBA functions for all the functionality of the __vba. It can be said that the VBA function started from__vba is an optimized version of the VBA function starting at the beginning of the RTC. They are basically the VB development team rewrote, and most of them implement their own functions inside the function, and most of the RTC starts to call COM Service objects are completed. It can be seen from the function of so many __vba's beginning, the VB group has been optimized in Native Code (local code), which is not a lot of effort. It is indeed highly optimized a number of scientific computing related functions, and ABS is more than 4 times more than P-CODE in ABS. But not all calculation functions have been optimized, such as RND functions, there is no optimization function of the beginning of __vba, but directly to the RTCrandomnext function, although RtcrandomNext has been optimized, but inside is still used The COM call is still not as fast as he rewritten. I don't understand why the VB Development Team does not consider writing a corresponding __vbarnd. Don't think that the above analysis is meaningless, because we can see the nature from the phenomenon, or from essence. For example, let's join a class module for your code, you can try to declare a public approach to the same name as the internal method (this is a very useful technology, "wrong handles" behind this series This method will be used), such as we can declare a public function rnd (x) as single, and we can write a same name MsgBox. But you can try a public function abs (x). At this time, VB will definitely pop up a inexplicable compilation error message telling you "missing identifier", this error occurs in your function name and VB keyword conflict time.
But why is the function in the Math module, ABS is keyword, RND is not, the VB document will not tell you why, but if you seriously read the experimental analysis above, we can guess this because VB has been highly optimized for functions that need further optimization. In order to protect their labor results and show their self-confidence of their optimization technology, but the VB development team also admits others. The function needs to be further optimized, so we can rewrite it. Here I want to propose a great conjecture: Any function that can be rewritten can be optimized, as if the even number of greater than 2 can be broken down into two prismatic factors. Speaking of optimization, you should also talk about the difference between the direct API call and use the API type library, you must also talk about the backend optimizer used by VB (the same optimizer as VC), but also want to talk about how to It is possible to use vTable bindings ... (Preparing to write "optimization" in this series to talk about these issues). After reading the local code, let's take a look at P-Code. If you read the principle of the P-Code in MSDN, you will definitely be big. Flatherapy, P-CODE is really a great technology, and the code size can be reduced by 50%. We compile the program 2 into a P-code to see, or use Depend to observe, it is found that it does not introduce the __vba start function (without using an optimized VBA function?), It introduces something such as Callengine (definitely to call P -code pseudo code interpretation engine), and the RTCMSGBOX is introduced like Native Code (compiled P-CODE should be faster than the P-Code that is running in the IDE environment when calling MSGBox). If you can't wait to run the program 2, you will find that it will pop up an application error dialog, saying that the program exceptions. Don't be afraid, this is because calling the DebugBreak this API, this API is actually generating an int 3 interrupt, making us interrupt the program execution. If you have installed the VC to support instant debugging debuggers, you can click "Cancel" in the error dialog, which can start the debugger to debug the program. I am running like this. If you want to see the VB generated program disassembly code can try it yourself, we can use the same technique to interrupt the program in the Ide of VB or VBA, such as we can run the above program in the Word's VB editor 2 The code is interrupted in the process of Word, and the P-CODE code generated by VBA can be observed. For example, the P-CODE code generated by VB and VBA in the IDE will find that they have great differences. Therefore, the procedures running in the IDE and the final generated procedures are completely different. Use Spy to see the form you run in IDE, you will find it under the host thread of VB, that is, in the IDE you use the form and the VB IDE work window belong to VB IDE, your The resources applied for the program are also available in VB IDE when running in IDE. Some procedures will run in the IDE to let IDE die (write pure API multithreading in VB5, don't run in IDE, dying is undoubtedly, which is much more strong than VB6). Others may work normally in the IDE, but you can't work after generating EXE. In summary, this different possible problems should be taken into account when writing a system program. 3) VB compilation technology, how can I praise you, but I want me to marry you. I saw the highly evaluation of Native Code, you might be more confident, the waist is more straight.
Yes, as a VB programmer does not need to be shy, a profound VB programmer should take more salary for ordinary VC programmers, because his productivity is several times that of VC programmers, and the procedure made Quality is different from VC. Even Master is joking, VB's built-in object is written with VB, such as we can write form.cls, label.ctl, huh, we really can't rule out this possibility (although it is not possible to generate VB6 with VB. OLB). If this is true, it seems that the VB group himself is very confident on his compilation optimization technology. In fact, we look at the attributes of C2.exe in the VB installation directory, then look at the attributes of the VC's C2.DLL, it will find that they are the same thing, the same link.exe is also VC, so we can completely pair VB The backend optimization compiler of the program and the coupling are relieved. They are all VC development group, or VB, VC is the same compiler development team to do compilation modules. In short, we can be boldly said that our VB did the second optimization and linkage for the same technology as VC. Hey, you have some, I have some (pure sophisticated). Also, no compiler is faster than the VB compiler, because VB in the IDE is an interpretation language, this is the key to the high VB development efficiency, so almost no compilation process. Its request is compiled, and the background compilation technology is even more unique, it is powerful! Think about it, how much time is spent in other languages, waiting for the code compilation and reconnection! Don't be too early, because the ultimate goal is to generate an executable. In VB, there is no blockbuster, and VB always compiles all modules and completely reconnects when generating executable programs, and we can compile the most recently modified files in other compile languages. Compilation), attach the newly generated code when the newly generated code is attached to the executable, and the original generation is marked as invalid (incremental connection, the final executable will get bigger and bigger, but the connection time is greatly shortened). Do experimentally, it will find that it takes the same time to generate an executable in VB. I don't know why the VB Development Team does not provide block compile and incremental linkages. It may be that the VB Development Team believes that generating executables is not often doing in VB. But in fact, this reason is that it can't be in the past, as running procedures and final procedures in the previous IDE, if we want to compile executable files, you can truly make Profile, as we want to debug multithreading The program cannot do in VB IDE. After each of these cases, re-generate executables after each modification, we waste a lot of time to compile the compiled code, join the program that has been coupled. I suspect that this is because VB generates executable programs for global optimization, so you must have all recompiled linkages. But providing a new feature allows us to generate a debugging version that can be divided into bilochemical, it should be difficult to do it for the VB development group! (I have a variable solution, still in the test) to see VBAEXE6.LIB in the VB6 installation directory, how only 1K is big, can guess should not have code, most of them are functions such as vtile Address jump table, or some global constant, I don't know. But at least the VB can be used in a static link, why not provide this feature to us, let us have more choices. Do another experiment to see, do a standard EXE project, there is only one standard module in the module, and there is no in the module, and there is nothing in Sub Main, and it generates it as an EXE file.