Delphi Make DLL

Source: Internet
Author: User

One, open your first DLL project1.file->close all->file->New﹝dll﹞ Code://automatically generate code as followslibrary Project2; //that's a piece of crap .uses sysutils, Classes; {$R*.  RES} begin end. 2. Add a Func in: Code: library Project2; Uses sysutils, Classes; Function Mymax (X, Y:integer): integer; stdcall; BeginifX >Y then Result:=XElseResult:=Y; end;//Remember: The name of the Library is not the case, but Dll-func's case is related. //in Dll-func-name written Mymax and Mymax are different. If you write it wrong, immediately//The result is that the AP you call this DLL is not open at all. //The case of the argument is fine. Not even have the same name. As in the prototype (X,y:integer) but cited//Time to write (A,b:integer), it is not related. //Remember: Add another stdcall. The book says, if you are using Delphi to write DLLs, and hope not only to give//Delphi-ap also hope Bcb/vc-ap and so on use, then you better add a stdcall;//parametric Patterns: Delphi has a variety of its own variable patterns, which of course are not DLLs like//, Windows/dll's native language should be c. So if you want to pass in the parameters of the outgoing DLL, we//use the rules as much as you can. These two are written, the latter will be a lot of trouble. If you're not familiar with C ,//, that's okay. We'll talk about it later. {$R*.  RES} begin end. 3. Send these shareable func out DLLs so that the outside ﹝ is your delphi-AP ﹞ use: Light So, your AP can not use these, you have to add a exports. Code: {$R*.   RES} exports Mymax;  Begin end. 4. OK, you can press CTRL-F9 to compile. Do not press F9 at this time. DLL is not exe┌ can not be executed alone, if you press F9, there will be errormsg. If the DLL has an error, please correct it. Press CTRL-F9 again. At this time may have warning, does not matter, studies, looks good. Press CTRL-F9 again, at this time "done, Compiled". There will be a * in the same directory. dll. Congratulations, it's done. Second, the test: Open a new application:1. Add a TButton code: ShowMessage (IntToStr (Mymax (30,50)) ) ; 2. Tell EXE to go there and grab a func code://after the Form,interface,var, addFunction Mymax (X, Y:integer): integer; stdcall; External ' MyTestDLL.dll ' ; //MyTestDLL.dll name of the DLL project you wrote before//DLL name case does not matter. But remember to add extension. Dll. In Win95 or NT,//There is no need to add extension, but these two OSes may be getting smaller. To add extensionYes, it's easy. Is the above example very simple? Familiar with Delphi friends can see that the above code and the General Delphi program is written basically the same, just after the Testdll function more than a stdcall parameter and exports statement declaration Testdll function. Just compile the above code, you can Mei Jie Huan Luo 狣 elphi.dll dynamic link library. Now, let's take a look at some of the areas that need attention:1A function or procedure written in a DLL must be prefixed with the stdcall invocation parameter. In the Delphi 1 or Delphi 2 environment The call parameter is far. This parameter has been changed from Delphi 3 to StdCall, in order to replace the optimized register parameter with the standard WIN32 parameter passing technique. Forgetting to use the stdcall parameter is a common error that does not affect the compilation and generation of DLLs, but when this DLL is called, a very serious error occurs that causes the operating system to deadlock.   The reason is that the register parameter is the default parameter for Delphi. 2The functions and procedures that are written should be declared as external functions with the exports statement. As you can see, the Testdll function is declared as an external function. This allows the function to be seen externally, by using the right mouse button to view the DLL file with the Quick View feature. (If there is no quick view option, you can install it from the Windows CD.) The Testdll function appears in the Export table column.   Another good reason is that if you do not declare it, the function we write will not be called, which is something that no one would want to see. 3to reference Sharemem when a parameter of a long string type is used, a variable. The string type in Delphi is very powerful and we know that the normal string length is up to 256 characters, but the string type in Delphi can be up to 2G in length by default. (yes, you're not mistaken, it's really two trillion.) At this point, if you insist on using a string type argument, variable, or even record information, you reference the Sharemem cell and must be the first one to refer to. The cell that is the first to be referenced, both after a uses statement. The following example: Uses Sharemem, sysutils, Classes; there is also a point in your project file (*.DPR) Instead of the unit file (*.pas), the same work is done, which is not clear from the Help file that Delphi brought, causing a lot of misunderstanding. If you don't do this, you're likely to pay the price of the crash. The way to avoid using string types is to declare arguments of type string, variables, and so on as Pchar or shortstring (for example: s:string[10]) type. The same problem occurs when you use a dynamic array, as described in the previous method. Method of making DLL with Delphi General steps to make a DLL the initialization and exit cleanup of the three DLLs [if necessary initialization and exit cleanup] Four global variables use five calls static load six call dynamic load seven in DLL build a tform eight in DLL Build a Tmdichildform Nine example: 10 Delphi DLL and other languages mixed programming often encountered problems: 11 related data A DLL is generally divided into the following steps:1. Write a procedure or function in a DLL project2write a exports keyword, under which the name of the process is written.  Do not write parameters and call suffixes. Two-parameter delivery1. Parameter types are best with window C + +parameter types are consistent.  Do not use Delphi's data type. 2. It is preferable to have a return value [even a process] to report the invocation success or failure, or state. The return value of success or failure is best 1[success] or 0[failed]. In a word, with Windows C + +compatible. 3. Declare the suffix with stdcall. 4. It's best to be case sensitive. 5. You do not need to use the far call suffix, only for compatibility with Windows 16-bit programs. Initialization and exit cleanup of three DLLs [if necessary to initialize and exit cleanup]1 . A pointer of the dllproc[sysutils unit] is the entry for the DLL. Here you can replace its entry with your function. But your function must meet the following requirements [is actually a callback function].   As follows: Procedure Dllenterpoint (Dwreason:dword); far;stdcall; The Dwreason parameter has four types: Dll_process_attach: When the process enters the dll_process_detach process exits when the Dll_thread_attach thread enters the Dll_thread_detach thread exits when the initial Part of the Write: Dllproc:=@DLLEnterPoint;   Dllenterpoint (Dll_process_attach); 2If there is a tdcomconnection component on the form, uses Activex, write a CoInitialize (nil) at initialization; 3. Be sure to dcomconnection.connected when exiting: =False, and the dataset is closed.  Otherwise the address is wrong. Use of four global variables in a widnows 32-bit program, the address space of two applications is not associated with each other. Although the DLL is in memory, the variable is in the address space of each process, so you cannot use the DLL's global variables to pass data between two applications unless you are using a memory image file. Five calls static loading1client function Reputation:1) is case sensitive. 2) is the same as the declaration in the DLL. such as: ShowForm (Form:tform); Far;external' Yproject_dll.dll ';3) Calling simultaneous past parameter types is best also with Windows C + +The same. 4The DLL must be in the Windows search path at the time of invocation, in the following order: current directory, path path; Windows;widows/system;windows/Ssystem32; Six call dynamic loading1. Create a process type [if you are clear about the nature of a pointer to a variable of the process type, you know what's going on]. such as: Type Mypointer=procedure (Form:tform);  far;external;    var Hinst:thandle;  Showform:mypointer; Begin Hinst:=loadlibrary (' Yproject_dll ');//load a DLL and search by file name. Showform:=getprocaddress (Hinst, ' showform ');//Search by function name, case sensitive. If you know the nature of the automation object is clear. ShowForm (Application.mainform);//called when a function entry pointer is found. FreeLibrary (Hinst);   End Seven. Create a tform in the DLL1uses your form into a DLL, the associated unit of your form is also uses in [this is the most troublesome point, because your form may uses many special units or functions]2pass a application parameter and use it to create a form. Eight. Create a tmdichildform in the DLL1the Mdiform.formstyle in the DLL is not fmmdichild.2after CreateForm write the following two sentences: function ShowForm (mainform:tform): Integer;stdcall var Form1:tform1;  Ptr:plongint; Begin PTR:[Email protected] (Application.mainform);//Save the DLL's mainform handle first, and no need to release it, just replace it .Ptr^:=longint (MainForm);//Replace the DLL's mainform with the mainform of the keynote program.    MainForm is a special window that specializes in managing forms resources in application. //why not directly application.mainform: = MainForm because Application.mainform is a read-only propertyForm1:=tform1.create (MainForm);//set with Parametersend;  Note: The parameter is the application.mainform of the keynote program nine. Example: DLL source code: library Project2; Uses Sysutils, Classes, Dialogs, Forms, Unit2 in' Unit2.pas '{FORM2}; {$R*.  RES} var Ccc:pchar;  Procedure OpenForm (mainform:tform); stdcall;    var Form1:tform1;  Ptr:plongint; Begin PTR:=@ (application.mainform); PTR^:=Longint (mainform); Form1:=tform1.create (mainform);  End  Procedure INPUTCCC (Text:pchar); stdcall; Begin CCC:=Text;  End  Procedure Showccc;stdcall;  Begin ShowMessage (String (CCC));  End    Exports OpenForm;  INPUTCCC, SHOWCCC;   Begin end.  Call FountainVest Partners Code: unit UNIT1; Interfaceuses Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs, Stdctrls; Type TForm1=class(tform) Button1:tbutton;  Button2:tbutton;  Edit1:tedit;  Procedure Button1Click (Sender:tobject);  Procedure Button2click (Sender:tobject); Private{Private declarations} Public{public declarations} end;  var Form1:tform1; Implementation {$R*. DFM} procedure OpenForm (mainform:tform); stdcall; External' Project2.dll '; Procedure Showccc;stdcall; External' Project2.dll '; Procedure INPUTCCC (Text:pchar); stdcall; External' Project2.dll ';  Procedure Tform1.button1click (Sender:tobject);  var Text:pchar; Begin Text:=Pchar (Edit1.text); //OpenForm (application.mainform);//to tune MDIChildINPUTCCC (Text);//to test whether global variables in the DLL are shared across applicationsend;  Procedure Tform1.button2click (Sender:tobject); Begin SHOWCCC;//This indicates that the global variables in the Windows 32-bit application DLL are also in the application address space, and the 16-bit applications may be different, without experimenting. end; Ten Delphi-made DLLs and other languages in the mixed programming often encounter problems:1. Mixed programming with PowerBuilder in defining a variable-length dynamic array, when the function exits the cleanup stack, the old occurrence of an unrecoverable address error is unexplained, presumably related to the PB compiler principle, even if PB is compiled into binary code. In Delphi it is easier to call a DLL in a static call than to write a DLL. The first is to introduce the static call method, the dynamic call method will be introduced later, and a comparison of the two methods. Again, let's start with an example of a static call. Unit Unit1; Interfaceuses Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs, stdctrls; type TForm1=class(tform) Edit1:tedit;     Button1:tbutton;   Procedure Button1Click (Sender:tobject); Private{Private declarations} Public{public declarations} end; var Form1:tform1; implementation {$R*. DFM}//our code below is the code we actually write.function Testdll (i:integer): integer;stdcall; external ' Delphi.dll '; procedure Tform1.button1click (Sender: TObject); Begin Edit1.text:=inttostr (Testdll (1)); End End. In the example above we put an edit box and a button on the form, and we wrote very little code to test the Delphi.dll we just wrote. As you can see, the only work we do is to place the description of the Testdll function in implementation and specify the location of the Delphi.dll with the external statement. (In this case, the calling program and the Delphi.dll are in the same directory.) It is exciting that the Testdll function we wrote ourselves was soon recognized by Delphi. You can do such an experiment: Enter "Testdll (", Soon Delphi will fly-the by hint bar indicates what parameters you should enter, just as simple as the other functions defined in Delphi. Note that there are some of the following: First, the invocation parameter is the same as mentioned earlier, when referencing the functions and procedures in the DLL, you also use the stdcall parameter, for the same reason as mentioned earlier. stdcall Ii. specifying the path and name of the called DLL file with the external statement as you can see, we specify the name of the DLL file to invoke in the external statement. There is no write path because the DLL file is in the same directory as the main program that called it. If the DLL file is in C:/, we can write the above reference statement as external ' c:/Delphi.dll '. Note the file suffix. dll must be written on. Third, cannot call global variable from DLL if we declare a global variable in the DLL, such as: var s:byte. In this case, the s global variable in the DLL can be used normally, but s cannot be used by the calling program, and S cannot be passed as a global variable to the calling program. However, variables declared in the calling program can be passed as arguments to the DLL. It is important that the called DLL must exist, and that the calling DLL file and the function or procedure to be called must exist when using the static call method. If it does not exist or if the specified path and file name are incorrect, the system prompts "error starting program" or "failed to find" when running the main program .*. dll file "run errors. Dynamically invoking DLLs in Delphi dynamically calls DLLs is a lot more complex, but very flexible. To fully illustrate the issue, this time we lift a call by CExamples of DLLs written in + +. First in C + +The following DLL source program is compiled. #include extern "C" _declspec (dllexport)intWINAPI TESTC (inti) {returni;} Compiled into a DLL file, where we call the file Cpp.dll, there is only one function in the DLL that returns an integer type TESTC. To make it easier to explain, we still refer to the above calling program, just replace the statement in the original Button1Click process with the following code. Procedure Tform1.button1click (Sender:tobject); Type Tintfunc=function (I:integer): Integer;stdcall; var th:thandle;   Tf:tintfunc; Tp:tfarproc; Begin Th:=LoadLibrary (' Cpp.dll '); {Load DLL}ifTh>0 ThenTryTp:=GetProcAddress (Th,pchar (' TESTC ')); ifTp<>Nil THEN begin TF:=Tintfunc (Tp); Edit1.text:=inttostr (Tf (1)); {Call TESTC function} endElseshowmessage (' testc function not found '); finallyFreeLibrary (TH); {Release DLL} endElseshowmessage (' Cpp.dll not found '); end; As you've seen, this dynamic invocation technique is complex, but as long as you modify the parameters, such as modifying the DLL name in LoadLibrary (' Cpp.dll ') called ' Delphi.dll ', you can dynamically change the called DLL. Define the type of function or procedure to invoke in the code above we define a tintfunc type, which corresponds to the function we are going to call TESTC. The same definition work should be done in other invocation cases. And also add the stdcall call parameter.   Second, release the called DLL we call a DLL dynamically with LoadLibrary, but remember that you must manually release the DLL with FreeLibrary after use, or the DLL will take up memory until you exit Windows or shut down. Now let's evaluate the pros and cons of the two methods of invoking DLLs. Static methods are simple, easy to master and generally a little faster and more secure, but static methods do not have the flexibility to unload the required DLLs at run time, but instead load the specified DLLs when the main program starts running and then release the DLL when the program ends. In addition, the method can be used only by compilers and linker-based systems such as Delphi. The dynamic method solves the shortcomings in the static method, it can easily access the functions and procedures in the DLL, even some new functions or procedures in the old version dll, but the dynamic method is difficult to grasp completely, because different functions or procedures need to define many complex types and calling methods. For beginners, I recommend that you use static methods, and then use the dynamic call method until you are proficient. Practical tips for using DLLs First, writing tips1, in order to ensure the correctness of the DLL, can be written into a common part of the application, debugging error and then separated from the main program, compiled into a DLL. 2, in order to ensure the universality of the DLL, the name of the visual control should be eliminated in the DLL you write, such as the Edit1 name in Edit1.text, or a custom non-Windows defined type, such as a record. 3, for ease of debugging, each function and procedure should be as short and concise as possible, with detailed comments. 4, should use more try-finally to handle possible errors and exceptions, note that you are referencing the Sysutils cell. 5, and as few references as possible to reduce the size of the DLL, especially if you do not reference a visualization unit, such as a dialogs cell. In general, for example, we can not reference the classes unit, which reduces the compiled DLL by approximately 16Kb. Second, the call technique1. When using a static method, you can rename the called function or procedure. In the previously mentioned DLL example written in C + +, if you remove the extern "C" statement, C + + will compile some strange function names, the original TESTC function will be named @testc$s and so on ridiculous strange name, this is because C + + uses the C + +name mangling technology. This function name is illegal in Delphi, we can solve this problem: rewrite the reference function as function TESTC (I:integer): Integer;stdcall;   External ' Cpp.dll '; name ' @TestC $s '; the role of name is renaming. 2, can put the dll we write into the Windows directory or windows/the system directory. This allows you to write only the name of the DLL in the external statement or in the LoadLibrary statement without writing the path. But this is a bit inappropriate, these two directories have a large number of important system DLLs, if you make a DLL with their name, the consequences of this is unthinkable, and your programming technology is not enough to put your own DLL into the system directory of the point! Three, debugging Skills1, we know that DLLs are not to be run and single-step debugging when writing. There's one way to do it, that's in run|.set a host program in the Parameters menu.   The name of the host program is added to the host application column on the local page for single-step debugging, breakpoint observation, and operation. 2. Add the version information of the DLL. The prologue mentions that version information is important for DLLs, and if the version information is included, the size of the DLL increases by 2KB. It is worthwhile to add such a little space. Unfortunately, if we use project| directly,The version option in the Options menu is not available, which is not mentioned in Delphi's Help file, which I found, as long as one line of code is added. The following example: library Delphi; Uses sysutils, Classes; {$R*. RES}//Note that this line of code must be added to this positionfunction Testdll (i:integer): Integer;stdcall; begin Result:=i; end; exports testdll; Begin end.3, in order to avoid the same name as other DLLs, it is best to use a combination of character numbers and underscores when naming DLLs that you write.   such as: Jl_try16.dll. 4, if you have already compiled some DLLs in Delphi 1 or Delphi 2, the DLL you originally compiled is 16-bit. You can get 32-bit DLLs as long as the source code is recompiled in the new Delphi 3 or Delphi 4 environment. [PostScript]: In addition to the DLL described above the most commonly used methods, DLLs can also be used to do the resources of the carrier. For example, changing an icon in Windows is a resource in a DLL that is used.       In addition, mastering the design techniques of DLLs has many benefits for using more advanced OLE, COM, and ActiveX programming. Suggestions for using Delphi to make DLL reuse files in the company there are some need to make DLLs, because familiar, convenient and easy, most of the use of Delphi to make. Now make some personal suggestions on this subject. Use standard DLL interfaces as much as possible. Refers to the type of arguments passed and the function return type cannot be unique to Delphi, such as String (ansistring), and dynamic arrays and composite types that contain these types of members (such as records), or object types that contain data members of these type members, to avoid possible errors. If a string type or dynamic array type is used, and the caller is not a Delphi program, the error will be basically.  An error can also occur if the caller is Delphi but the caller or callee is not sharemem in the first containing unit of the project file.  If the caller is a Delphi application, you may be able to use an object that does not contain a prohibited type (string, dynamic array) data member as a parameter or return value, but should be avoided as much as possible. If both the caller and the callee are Delphi programs, and you want to use a string or dynamic array as arguments, the first containing unit of the project file for both parties must be sharemem. (C++the builder program may have the same situation, but it has not been tested.  If the caller is not a Delphi program, a string, a dynamic array, a composite data type that contains a string or a dynamic array, and a class instance cannot be used as parameters and as return values. Therefore, in order to improve the reuse scope of the DLL and avoid possible errors, you should use the standard WIN32 API standard parameter type, which previously used a variable of string, can be converted using Pchar (s). Dynamic arrays are converted to pointer types (@array [0]), plus the length of the array. If both the caller and the callee are Delphi programs, it is recommended to use the form of the run-time package in order to be easy to write and do not want to do the above conversions. The run-time package guarantees the correct release of dynamically allocated data. This is due to its extension (. bpl), which shows that the file is limited to Delphi/c++Builder is used (not like a DLL). Second, try to avoid using the overload function/process as output, if there are multiple ways for the same operation, you can let the function/The process name is slightly different, similar to Delphi in the Formatxxxx, createxxxx and other functions and methods, such as Createbydefaultfile, Createdefault. Finally, as a DLL provider, you should provide direct programming interface files, such as the. pas or. DCU in Delphi (preferably. Pas, because there can be comments), C, and CThe. h and. Lib in + +. Instead of letting users create it themselves. This is especially important if you want to have a overload function/process. In addition, as a Delphi application, the provided. pas file can be pre-connected (using external to specify the output function in the DLL), or it can be late-connected (using LoadLibrary, GetProcAddress), the DLL provider provides the programming interface file, It is both formal (or Hiqos) and secure.

Delphi Make DLL

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.