动态库的编写和调用 Delphi 2

uDll.pas
  function Add10(ANum: integer): integer; stdcall; //Delphi 默认采用 register 调用约定,如果dll涉及跨语言调用,最好

明确指出采用 stdcall 调用约定

library MyDll;


uses

  ShareMem;  // 如果dll 涉及长字符串的参数或变量,需要在 uses 第一的位置引用 ShareMem 单元。


exports  

  Add10;


可以使用标准指令以方便和加速过程、函数的调用。即 name,index,resident
  Add10 name 'NewAdd';  //如果不写 name,默认以过程或函数最初声明的名称为准  

  Add10 index 1;     //如果不写 index,默认编译器按顺序自动分配;index指令只对 windows 系统有用如果要同时使用 name 和 index ,那么 index 必须置于 name 前面    

resident 主要为了向后兼容,编译器将忽略它


注意: exports 可以导出重载(overload)函数,但书写函数时必须加上参数。例如:
Add10(ANum: integer) name 'Add10_Int';

Add10(Anum: real)    name 'Add10_Real'; //可以加一个 name 分别标示名称。 重载时一定不能用 index 指令

在 Widnows 32 位程序中,两个应用程序的地址空间是相互没有联系的。DLL 在内存中是一份拷贝(每个应用程序的进程空间各自拥有该 DLL 的一个副本及自身的一套全局变量),而变量是在各进程的地址空间中,因此不能借助 DLL 的全局变量来达到两个应用程序间的数据传递,除非使用内存映像文件。

调用 dll:
(1)静态调用
function Add10(ANum: integer): integer; stdcall; external 'MyDll.dll';
注意:
•  必须用 stdcall 作为调用参数。 
•  大小写敏感。与 Delphi 程序不同,调用动态链接库是大小写敏感的

(2)动态调用
type   
  TAdd10 = function(ANum: integer): integer; stdcall; 

const  
  MyDllName = 'MyDll.dll';

var   
  handle:THandle ;   
  FPointer: TFarProc;   
  MyFunc : TAdd10 ; 
begin  
  handle := LoadLibrary(MyDllName);                   {装载 DLL 到内存}   
  if handle <> 0 then  begin   
    try       
      FPointer  := GetProcAddress(handle, 'Add10’);  {获得函数的入口地址}       
      //@MyFunc := GetProcAddress(handle, 'Add10’);       
      //if @MyFunc <> nil then  //也可以采用这种编写方式      
      if FPointer  <> nil then  begin         
        MyFunc := TAdd10(FPointer) ;        
        …………      
      end;    
    finally      
      FreeLibrary(handle);                            {释放 dll}    
    end;  
  end; 
end; 

原文地址:https://www.cnblogs.com/sikale/p/1970342.html