我想创建一个用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;
答案 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
。