从Ada调用动态DLL详解Init

时间:2014-05-27 20:30:28

标签: dll ada

我想创建一个用ADA编写的DLL,可以从C ++或ADA调用。我编译了DLL,它导出了我的函数以及Init和Final。

我现在想使用动态链接从Ada调用此DLL。下面代码的前半部分调用C ++ dll(没有Init和Final)。这很好用。下半部分在调用DLL的函数之前尝试运行Init。但是用大量星号标识的行将无法编译,而是出现错误:缺少操作数。

我哪里错了?

with Ada.Text_IO;  use Ada.Text_IO;

with Interfaces;   use Interfaces;
with Interfaces.C; use Interfaces.c;
with System;       use System;

with Ada.Unchecked_Conversion;

procedure SmallCode is
    -- Definitions for dynamic DLL interface
    type HANDLE is new Unsigned_32;
    function LoadLibrary (lpFileName : char_array) return HANDLE;
    pragma Import (stdcall, LoadLibrary, "LoadLibrary", "_LoadLibraryA@4"); -- Ada95 doesn't use @n

    function GetProcAddress (hModule : HANDLE; lpProcName : char_array) return Address;
    pragma Import (stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress");
    --
    -- The interface of the function we want to call.  It is a pointer (access type) because
    -- we will link it dynamically.  The function is from AdaCallable.dll
    type fnAdaCallable is access function(val : Integer_32) return Integer_32;
    pragma Convention (Stdcall, fnAdaCallable);
    function To_fnAdaCallable is new Ada.Unchecked_Conversion (Address, fnAdaCallable);
    Pointer : Address;
    function To_AdaCallable is new Ada.Unchecked_Conversion (Address, fnAdaCallable);
    Pointer2 : Address;

    type fnInit is access procedure;
    pragma Convention (Stdcall, fnInit);
    function To_fnInit is new Ada.Unchecked_Conversion (Address, fnInit);
    PointerInit : Address;

    type fnFinal is access procedure;
    pragma Convention (Stdcall, fnFinal);
    function To_fnFinal is new Ada.Unchecked_Conversion (Address, fnFinal);
    PointerFinal : Address;

    Library : HANDLE;

begin
    Library := LoadLibrary (To_C ("AdaCallable.dll"));
    if Library /= 0 then

        Pointer := GetProcAddress(Library, To_C("_fnAdaCallable@4"));

        if Pointer /= Null_Address then
            declare
                result : Integer_32;
            begin

                result := To_fnAdaCallable(Pointer) (74);
                Put_Line("Returned result is " & Integer_32'Image(result));
            end;
        else
            Put_Line("GetProcAddress returned Null_Address");
        end if;
    else
        Put_Line("LoadLibrary returned 0");
    end if;
    Library := LoadLibrary (To_C ("libDllBuiltFromAda.dll"));
    if Library /= 0 then
        PointerInit := GetProcAddress (Library, To_C ("DllBuiltFromAdainit"));
      if Pointer /= Null_Address then
            Put_Line("Calling Init");
            To_fnInit (PointerInit);  -- ****************************************
            Put_Line("Returned from Init");

            Pointer2 := GetProcAddress(Library, To_C("AdaCallable@4"));
            if Pointer2 /= Null_Address then
                declare
                    result : Integer_32;
                begin

                    result := To_AdaCallable(Pointer2) (74);
                    Put_Line("Returned result is " & Integer_32'Image(result));
                end;
            else
                Put_Line("GetProcAddress returned Null_Address");
            end if;

            PointerFinal := GetProcAddress (Library, To_C ("DllBuiltFromAdafinal"));
         if Pointer /= Null_Address then
                Put_Line("Calling Final");
                To_fnFinal (PointerFinal);
                Put_Line("Returned from Final");
            else
                Put_Line ("GetProcAddress for final returned Null_Address");
            end if;
        else
            Put_Line ("GetProcAddress for Init returned Null_Address");
        end if;
    else
        Put_Line("LoadLibrary returned 0");
    end if;
   Put_Line ("Hello, World!");
end SmallCode;

1 个答案:

答案 0 :(得分:3)

鉴于

type Proc_P is access procedure (X : Integer);
P : Proc_P;

你可以写

P (42);

作为

的简写
P.all (42);

但如果没有参数列表来触发快捷方式,则必须明确:给定

type Parameterless_Proc_P is access procedure;
Q : Parameterless_Proc_P;

你必须通过写

来调用该程序
Q.all;

顺便说一句,在你的星号线之前的第二行,我认为你的意思是PointerInit