Re: Problem creating bindings - please help
- From: "Steve" <nospam_steved94@xxxxxxxxxxx>
- Date: Thu, 18 May 2006 20:25:04 -0700
"Gerd" <GerdM.O@xxxxxxxxxxx> wrote in message
news:1147934783.645893.274580@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi all,
I tried to create my own Ada bindings for a dll, but I didn't succeed.
I haven't done this with GNAT, but I have done similar work with ObjectAda.
I have a few noted suggestions below.
The C-header contains:
DWORD __stdcall CAN_GetHwParam(
HCANHW hHw,
WORD wParam,
void* pBuff,
WORD wBuffLen);
My Ada-spec look like this:
with System;
with Interfaces;
package CanApi2 is
pragma Linker_Options ("-lCanApi2");
subtype
HCANHW is Integer;
You need to look up the definition of HCANHW to find out the size. I prefer
to use either:
Interfaces.Unsigned_16;
Interfaces.Unsigned_32;
Interfaces.Integer_16;
Interfaces.Integer_32;
Since you are working with an interface. Some people prefer to use types
defined in Interfaces.C, I prefer to be more explicit for interfacing.
subtype
Word is Integer;
Assuming you're working on Win32, this should be:
subtype Word is Interfaces.Unsigned_16;
function CAN_GetHwParam (hHw : HCANHW; wParam : Word; pBuff :
System.Address; wBuffLen : Word) return Integer;
private
pragma Import (Stdcall, CAN_GetHwParam, External_Name =>
"CAN_GetHwParam");
end CanApi2;
The lib-file (CanApi2.lib) contains this names:
_CAN_GetHwParam@16 __imp__CAN_GetHwParam@16 _CAN_SetHwParam@12
__imp__CAN_SetHwParam@12
And that's what I get when build my test-program:
C:\Work\CAN>gnatmake cantest
gcc -c cantest.adb
gcc -c canapi2.ads
gnatbind -x cantest.ali
gnatlink cantest.ali
./cantest.o(.text+0x264):cantest.adb: undefined reference to
`CAN_GetHwParam@16'
gnatlink: cannot call C:\GNAT\bin\gcc.exe
gnatmake: *** link failed.
DLL2DEF shows this:
EXPORTS
CAN_GetHwParam
So what's wrong with my code? Please help, thanks.
Gerd
The other thing I have moved toward is loading the dll dynamically at run
time. If the dll is loaded automatically when the program runs,
uncontrolled meaningless error messages (to an end user) appear and the
program fails. By loading dynamically I can put out a meaningful error
message. It is also easier to troubleshoot.
Here is an example of a few code fragments I use to set up a dynamic
interface to adagraph.
type PutpixelAccType is access
function(X, Y, Hue : Integer) return Integer;
pragma Convention( C, PutpixelAccType );
PutpixelAcc : PutpixelAccType;
function To_PutpixelAcc is
new Ada.Unchecked_Conversion( WinDef.FarProc, PutpixelAccType );
PutpixelProcName : C.Char_Array := C.To_C( "PutPixel" );
procedure Put_Pixel (X, Y : in Integer; Hue : in Color_Type := White) is
Return_Value : Integer;
begin
if PutPixelAcc /= null then
Return_Value := PutPixelAcc(X, Y, Color_Type'Pos (Hue));
if Return_Value < No_Errors then
Make_Exception (Return_Value);
end if;
end if;
end Put_Pixel;
-----------------------------------------------
adagraphLibraryName : C.Char_Array := C.To_C( "adagraph.dll" );
begin
adagraphDll := System.Null_Address;
adagraphDll := WinBase.LoadLibrary( adagraphLibraryName(0)'access );
...
PutpixelAcc := To_PutpixelAcc( WinBase.GetProcAddress( adagraphDll,
PutpixelProcName(0)'access ) );
....
I hope this helps,
Steve
(The Duck)
.
- References:
- Problem creating bindings - please help
- From: Gerd
- Problem creating bindings - please help
- Prev by Date: C++ from Ada, again
- Next by Date: Re: Multi-arch
- Previous by thread: Re: Problem creating bindings - please help
- Next by thread: C++ from Ada, again
- Index(es):