I want to create a DLL written in ADA that can be called from C++ or from ADA. I've compiled the DLL, and it exports my functions as well as Init and Final.
I now would like to call this DLL from Ada, using dynamic linking. The first half in the code below calls a C++ dll (without Init and Final). This works well. The second half tries to run Init before calling the DLL's function. But the line identified with lots of asterisks won't compile, instead I get error: missing operand.
Where am I going wrong?
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;