User Tools

Site Tools


tutorial:dlllibrary

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
tutorial:dlllibrary [2018/10/28 09:12]
admin
tutorial:dlllibrary [2019/03/15 10:42] (current)
admin
Line 8: Line 8:
 |  Linux  |  .so  | |  Linux  |  .so  |
 |  MacOS X  |  .dylib ​ |  |  MacOS X  |  .dylib ​ | 
-\\ \\+\\ 
 =====การสร้าง Shared Library===== =====การสร้าง Shared Library=====
 ใน Lazarus IDE เราสามารถสร้าง Shared Library ไว้ใช้งานสำหรับ Window, Linux และ MacOS X ได้ทั้งหมดครับ โดยการเลือกเมนู \\ ใน Lazarus IDE เราสามารถสร้าง Shared Library ไว้ใช้งานสำหรับ Window, Linux และ MacOS X ได้ทั้งหมดครับ โดยการเลือกเมนู \\
Line 47: Line 47:
   Run >> Compile   Run >> Compile
  
-เมื่อทำการ compile เสร็จเรียบร้อย เราจะได้ไฟล์ .dll ที่พร้อมใช้งานครับ ​+เมื่อทำการ compile เสร็จเรียบร้อย เราจะได้ไฟล์ .dll ที่พร้อมใช้งานครับ ​ให้นำไฟล์ .dll ไปไว้ใน folder เดียวกับไฟล์ Project เราได้เลย
  
 <hidden Example-1: Create .dll Library> <hidden Example-1: Create .dll Library>
Line 79: Line 79:
 =====การเรียกใช้งาน Shared Library===== =====การเรียกใช้งาน Shared Library=====
 การเรียกใช้งาน Shared Library สามารถเรียกได้ 2 แบบ ดังนี้ การเรียกใช้งาน Shared Library สามารถเรียกได้ 2 แบบ ดังนี้
-  *Static Calling คือการเรียกในขณะ Compile-time นั่นหมายถึงเวลาที่เราำไฟล์ .exe ไปแจ่ายนั้น ไมจำเป็นตองบไฟล์ .dll ไปใน Folder ​นื่องจาก code ต่างๆใน Shared Library ได้ถูก compiled ไว้ใไฟล์ ​.exe เรียบรอยแว วิธีเรียกแบบนี้ีข้อดีคือไม่ซัซ้อน แต่มีข้อเสียคือจะทำให้ไฟล์ของโปรแกรมที่เราเขียนขึ้น ​มีขนาดใหญ่ +  *Static Calling คือการเรียกทุก function จก Library ​มาเก็บไ้ใแกรมหลักตั้งแตต้น ยกัวย่าง เช่น เราต้องการใช้น function ทั้งหมด 5 ตัว ทุกครังที่มีารรัน .exe function ทัง 5 ตัวดังก่าว ก็จะถูกเรียกมาเก็นโปรแกรมเราตั้งแต่ต้น  
-  *Dynamic Calling คือการเรียกใช้ ​ในขณะ Run-time นั่นคือเวลาที่เรานำไฟล์ .exe ไปแกจ่ยนั้น จำเป็นต้องแนบไฟล์ .dll ไปใน Folder ทุครั้ง ​เพาะตัว ​Shared Library ไมได้ถูก ​Compiled ​เขากับฟล์ .exe ังนันจึงถูกเรียกมาใช้เฉพาะน้แทน ​วิธีเรียกแบบนี้จะต้องเขียน ​code ที่ค่อนข้าุ่ก แตอดคืจะทำห้ขนาดของโปรแกรเราไม่ใญ่มากและรายังสามารถ Update ​ไฟล์ .dll ได้นภยหลัง+  *Dynamic Calling คือการเรียกใช้ ​function ​จาก ​Library ​พาะตัวที่ถูกใช้งานจิง ไได้เรียกมาใช้ทั้งมดแต่แรก อย่งไรก็ตาม ​วิธีนี้จะยุ่งยากกว่าวิธีแรกพอสมควร เพราะต้องเขียน ​procedure/​function ​นมเป็นพิเศษเพื่อเรีกใช้งาน function เหลานันทละตัว ขครของมัน\\ 
 +หมาหตุ: ทงสองแบบ ต้องการไฟล์ .dll แนบช้งนกับไฟ์ .exe ด้วยทุกครง 
  
 <hidden Example-2: Static Calling .dll Library> <hidden Example-2: Static Calling .dll Library>
-**ตัวอย่าง** การเรียก Library ชื่อว่า Pipe เพื่อเก็บฟังก์ชั่นคำนวณหาพื้นที่หน้าตัดท่อ\\+**ตัวอย่าง** การเรียก Library ชื่อว่า Pipe (จาก Example-1) ​เพื่อเก็บฟังก์ชั่นคำนวณหาพื้นที่หน้าตัดท่อ\\
 __ข้อสังเกต__:​ ชื่อตัวแปร Argument ของในโปรแกรมนี้ ไม่ตรงกับใน .dll \\ __ข้อสังเกต__:​ ชื่อตัวแปร Argument ของในโปรแกรมนี้ ไม่ตรงกับใน .dll \\
   *ไฟล์นี้ ใช้ PipeArea1(const D,​Di:​double):​double \\   *ไฟล์นี้ ใช้ PipeArea1(const D,​Di:​double):​double \\
Line 112: Line 113:
   readln;   readln;
  
 +end. 
 +</​sxh> ​    
 +</​hidden>​
 +
 +<hidden Example-3: Dynamic Calling .dll Library>
 +**ตัวอย่าง** การเรียก Library ชื่อว่า Pipe (จาก Example-1) เพื่อเก็บฟังก์ชั่นคำนวณหาพื้นที่หน้าตัดท่อ\\
 +__ข้อสังเกต__:​ มีดังนี้ \\
 +  *จะต้องมี unit ชื่อ Dynlibs\\
 +  *จะต้องมีการเรียกใช้ function เป็นตัวแปร หรือที่เรียกว่า Procedural Type \\
 +<sxh delphi;​highlight:​ [8,​13-14,​20-35,​42]>​
 +program DynamicCalling_PIPEDLL;​
 +//This example demonstrates the simple use of static/​Dynamic calling.
 +//For calling convention, register is used by default.
 +
 +{$mode objfpc}{$H+}
 +
 +uses
 +  Classes,​Dynlibs;​
 +
 +function PipeArea1(const D,​Di:​double):​double;​{calling;​} external '​Pipe.dll';​
 +
 +//Define procedural type for Dynamic Calling
 +type
 +  TMyDLL = function(const D,​Di:​double):​double;​{calling;​}
 +
 +
 +
 +Var D,​Di:​double;​
 +
 +  function CallDLib(const D,​Di:​double):​double;​
 +  var
 +    MyHandle: TLibHandle;
 +    MyDLLFunc: TMyDLL;
 +  begin
 +    MyHandle := SafeLoadLibrary('​Pipe.dll'​);​
 +    if MyHandle<>​0 then
 +      begin
 +        MyDLLFunc := TMyDLL(GetProcedureAddress(MyHandle,'​PipeArea1'​));​
 +        if Assigned(MyDLLFunc) then
 +          result:​=MyDLLFunc(D,​Di);​
 +      end
 +    else
 +      result:=10;
 +    FreeLibrary(MyHandle);​
 +  end;
 +
 +begin
 +  writeln('​Example for calling .dll library named Pipe.dll'​);​
 +  D:=0.25;
 +  Di:=0.23;
 +  writeln('​Static Calling PipeArea1(D,​Di):​ ',​PipeArea1(D,​Di));​
 +  writeln('​Dynamic Calling PipeArea1(D,​Di):​ ',​CallDLib(D,​Di));​
 +  readln;
 end.  end. 
 </​sxh> ​     </​sxh> ​    
Line 129: Line 183:
 |  oldfpccall ​ |  RTR  |  Callee ​ | |  oldfpccall ​ |  RTR  |  Callee ​ |
  
-จากตารางข้างบนอธิบายถึงความต่างของแต่ละ Calling Convention ​ือทิศทางการใส่ค่าตัวแปร และการกำจัดค่าของตัวแปรใน Ram จะเห็นได้ว่า default, register และ pascal จะมีการใส่ค่าตัวแปรแบบ "​ซ้ายไปขวา"​ หรือ LTR (Left-to-Right) ในขณะที่ cdecl, interupt, safecall, stdcall และ oldfpccall จะใส่ค่าตัวแปรแบบ "​ขวาไปซ้าย"​ หรือ RTL (Right-to-Left) ​+จากตารางข้างบนอธิบายถึงความต่างของแต่ละ Calling Convention ​มีทั้งเรทิศทางการใส่ค่าตัวแปร และการกำจัดค่าของตัวแปรใน Ram จะเห็นได้ว่า default, register และ pascal จะมีการใส่ค่าตัวแปรแบบ "​ซ้ายไปขวา"​ หรือ LTR (Left-to-Right) ในขณะที่ cdecl, interupt, safecall, stdcall และ oldfpccall จะใส่ค่าตัวแปรแบบ "​ขวาไปซ้าย"​ หรือ RTL (Right-to-Left) ​
 \\ \\ \\ \\
 **__ข้อควรระวัง__** - หากเราระบุ Calling Convention ใน .dll ไม่ตรงกับการเรียกใช้ในไฟล์ .exe ก็อาจทำให้เกิดการใส่ตัวแปรในแต่ละ Argument ของ Procedure/​Function สลับกันได้ จะนำไปสู่การคำนวณที่ผิดพลาดอย่างแน่นอน ​ **__ข้อควรระวัง__** - หากเราระบุ Calling Convention ใน .dll ไม่ตรงกับการเรียกใช้ในไฟล์ .exe ก็อาจทำให้เกิดการใส่ตัวแปรในแต่ละ Argument ของ Procedure/​Function สลับกันได้ จะนำไปสู่การคำนวณที่ผิดพลาดอย่างแน่นอน ​
 \\ \\ \\ \\
-**__หมายเหตุ__** - การไม่ระบุ Calling Convention นั้น จะหมายถึงการเรียกใช้งานแบบ default ซึ่งตัว ​default สำหรับ FPC คือ register +**__หมายเหตุ__** - การไม่ระบุ Calling Convention นั้น จะหมายถึงการเรียกใช้งานแบบ default ซึ่ง default ​calling convention ​สำหรับ FPC คือ register 
-<hidden Example-3: Static Calling .dll Library using stdcall as calling convention>​+<hidden Example-4: Static Calling .dll Library using stdcall as calling convention>​
 **ตัวอย่าง** การเรียก Library ชื่อว่า Pipe เพื่อเก็บฟังก์ชั่นคำนวณหาพื้นที่หน้าตัดท่อ\\ **ตัวอย่าง** การเรียก Library ชื่อว่า Pipe เพื่อเก็บฟังก์ชั่นคำนวณหาพื้นที่หน้าตัดท่อ\\
-__ข้อสังเกต__:​ จะต้องมีการระบุ Calling Convention ทั้งใน .dll และโปรแกรมหลัก \\+__ข้อสังเกต__: ​เราจะใช้ Calling ที่ชื่อว่า stdcall ซึ่งจะต้องมีการระบุ Calling Convention ทั้งใน .dll และโปรแกรมหลัก \\
  
 <sxh delphi;​highlight:​ [8,13]> <sxh delphi;​highlight:​ [8,13]>
tutorial/dlllibrary.1540692730.txt.gz · Last modified: 2018/10/28 09:12 by admin