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:30]
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 80: Line 80:
 การเรียกใช้งาน Shared Library สามารถเรียกได้ 2 แบบ ดังนี้ การเรียกใช้งาน Shared Library สามารถเรียกได้ 2 แบบ ดังนี้
   *Static Calling คือการเรียกทุก function จาก Library มาเก็บไว้ในโปรแกรมหลักตั้งแต่ต้น ยกตัวอย่าง เช่น เราต้องการใช้งาน function ทั้งหมด 5 ตัว ทุกครั้งที่มีการรัน .exe function ทั้ง 5 ตัวดังกล่าว ก็จะถูกเรียกมาเก็บในโปรแกรมเราตั้งแต่ต้น ​   *Static Calling คือการเรียกทุก function จาก Library มาเก็บไว้ในโปรแกรมหลักตั้งแต่ต้น ยกตัวอย่าง เช่น เราต้องการใช้งาน function ทั้งหมด 5 ตัว ทุกครั้งที่มีการรัน .exe function ทั้ง 5 ตัวดังกล่าว ก็จะถูกเรียกมาเก็บในโปรแกรมเราตั้งแต่ต้น ​
-  *Dynamic Calling คือการเรียกใช้ function จาก Library เฉพาะตัวที่ถูกใช้งานจริง ไม่ได้เรียกมาใช้ทั้งหมดแต่แรก อย่างไรก็ตาม วิธีนี้จะยุ่งยากกว่าวิธีแรกพอสมควร เพราะต้องเขียน ​code มากกว่าวิธ\\+  *Dynamic Calling คือการเรียกใช้ function จาก Library เฉพาะตัวที่ถูกใช้งานจริง ไม่ได้เรียกมาใช้ทั้งหมดแต่แรก อย่างไรก็ตาม วิธีนี้จะยุ่งยากกว่าวิธีแรกพอสมควร เพราะต้องเขียน ​procedure/​function ขึ้นมาเป็นพิเศษเพื่อเรียใช้งาน function เหล่านั้นทละตัว ของใคของมัน\\
 หมายเหตุ:​ ทั้งสองแบบ ต้องการไฟล์ .dll แนบไปใช้งานกับไฟล์ .exe ด้วยทุกครั้ง ​ หมายเหตุ:​ ทั้งสองแบบ ต้องการไฟล์ .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 113: 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 130: 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.1540693800.txt.gz · Last modified: 2018/10/28 09:30 by admin