comp.lang.ada
 help / color / mirror / Atom feed
* DLL Troubles
@ 2006-03-19 18:46 cybersaga
  2006-03-19 19:22 ` tmoran
  2006-03-19 19:37 ` Jeffrey R. Carter
  0 siblings, 2 replies; 9+ messages in thread
From: cybersaga @ 2006-03-19 18:46 UTC (permalink / raw)


I have a DLL that gets dynamically loaded (in Windows) and contains a
function to return a random number as a subset of what it's supposed to
do.
However, it does not work. I keep getting a "raised PROGRAM_ERROR :
EXCEPTION_ACCESS_VIOLATION" when the DLL tries to reset the random
seed. I can do it fine within the main program, but not within the DLL.

The line in question is "RandomNum.Reset(Seed);". Looking at the call
stack when it dies, it shows that the Reset procedure calls
Calendar.Year (from Ada.Calendar), which calls Calendar.Split, which is
where the exception gets thrown.

I whipped up a stripped down proof of concept of the problem. Here is
the code for the DLL:
-----mydll.ads---------------------------------------
package MyDll is

   function GetRandom(Bottom, Top : Integer) return Integer;

   pragma Export_Function (
      Internal => GetRandom,
      External => "GetRandom",
      Parameter_Types => (Integer, Integer),
      Result_Type => Integer);

end MyDll;
------------------------------------
-----mydll.adb---------------------------------------
with Ada.Numerics.Discrete_Random;

package body MyDll is

   function GetRandom(Bottom, Top : Integer) return Integer is
      type NumRange is new Integer range Bottom .. Top;
      package RandomNum is new Ada.Numerics.Discrete_Random(NumRange);
      Seed : RandomNum.Generator;
   begin
      RandomNum.Reset(Seed);                             --It dies in
here
      return Integer( RandomNum.Random(Seed) );
   end GetRandom;

end MyDll;
------------------------------------

Here is the code for the main program:
-----bugtest.adb---------------------------------------
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Unchecked_Conversion;
with Ada.Numerics.Discrete_Random;
with Win32; use Win32;
with Win32.Windef; use Win32.Windef;
with Win32.Winbase; use Win32.Winbase;

procedure bugtest is
   type RandomF is access function(Bottom,Top : Integer) return
Integer;
   function Convert is new Ada.Unchecked_Conversion(FARPROC, RandomF);
   MyRandomF : RandomF;
   hDll : HINSTANCE;
   my_rand : Integer;

   type NumRange is new Integer range 1 .. 5;
   package RandomNum is new Ada.Numerics.Discrete_Random(NumRange);
   Seed : RandomNum.Generator;
begin
   --put out random number from main program (works fine)
   RandomNum.Reset(Seed);
   put(Integer(RandomNum.Random(Seed)));

   --now try through DLL (dies)
   hDll := LoadLibrary(Addr(".\dll\mydll.dll" & ASCII.NUL));
   MyRandomF := Convert( GetProcAddress(hDll, Addr("GetRandom" &
ASCII.NUL)));

   my_rand := MyRandomF.all(1,5);
   Put(my_rand);
end bugtest;
------------------------------------

Does anyone have any thoughts on why this is happening, and why only
from the DLL and not the main program?




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 18:46 DLL Troubles cybersaga
@ 2006-03-19 19:22 ` tmoran
  2006-03-19 19:27   ` cybersaga
  2006-03-19 19:37 ` Jeffrey R. Carter
  1 sibling, 1 reply; 9+ messages in thread
From: tmoran @ 2006-03-19 19:22 UTC (permalink / raw)


I don't see any Adainit call.
You don't say what compiler you're using - doesn't it want an initial
call to Adainit?



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 19:22 ` tmoran
@ 2006-03-19 19:27   ` cybersaga
  2006-03-19 19:30     ` cybersaga
  0 siblings, 1 reply; 9+ messages in thread
From: cybersaga @ 2006-03-19 19:27 UTC (permalink / raw)


I'm not entirely sure. The compiler doesn't complain about that at
least. I have another DLL that loads and works flawlessly without an
Adainit call, though that DLL doesn't use any outside packages.

I am using GNAT.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 19:27   ` cybersaga
@ 2006-03-19 19:30     ` cybersaga
  2006-03-19 20:13       ` Pascal Obry
  0 siblings, 1 reply; 9+ messages in thread
From: cybersaga @ 2006-03-19 19:30 UTC (permalink / raw)


A version might be useful: GNAT GPL 2005.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 18:46 DLL Troubles cybersaga
  2006-03-19 19:22 ` tmoran
@ 2006-03-19 19:37 ` Jeffrey R. Carter
  1 sibling, 0 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2006-03-19 19:37 UTC (permalink / raw)


cybersaga wrote:

Nothing to do with your problem, but:

>    function GetRandom(Bottom, Top : Integer) return Integer is
>       type NumRange is new Integer range Bottom .. Top;

And if Bottom > Top? You might want to look at the 'Min and 'Max attributes.

Why not use

subtype Numrange is Integer range Bottom .. Top;

>       package RandomNum is new Ada.Numerics.Discrete_Random(NumRange);
>       Seed : RandomNum.Generator;
>    begin
>       RandomNum.Reset(Seed);  --It dies in here
>       return Integer( RandomNum.Random(Seed) );

return Randomnum.Random (Seed);

>    end GetRandom;

You have no need for a new type.

-- 
Jeff Carter
"What I wouldn't give for a large sock with horse manure in it."
Annie Hall
42



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 19:30     ` cybersaga
@ 2006-03-19 20:13       ` Pascal Obry
  2006-03-19 20:23         ` cybersaga
  0 siblings, 1 reply; 9+ messages in thread
From: Pascal Obry @ 2006-03-19 20:13 UTC (permalink / raw)
  To: cybersaga

cybersaga a �crit :
> A version might be useful: GNAT GPL 2005.

In that case use a project file. It is so easy to build DLL with project
file. Moreover you'll be able to link directly to the DLL. Please be
sure to read the GNAT documentation and especially the Windows specific
section.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 20:13       ` Pascal Obry
@ 2006-03-19 20:23         ` cybersaga
  2006-03-19 21:19           ` cybersaga
  0 siblings, 1 reply; 9+ messages in thread
From: cybersaga @ 2006-03-19 20:23 UTC (permalink / raw)


Actually, I am using a project file, for both the dll and the main
program. Here's what the DLL's project contains:
-------mydll.gpr---------------------
project Mydll is
   for Source_Files use ("mydll.adb", "mydll.ads");
   for Library_Name use "mydll";
   for Library_Kind use "dynamic";
   for Library_Dir use "dll";
end Mydll;
-------------------------------------

As to "linking directly to the DLL", I need to be able to load the DLL
dynamically.

I'm beginning to believe this problem stems from my lack of an AdaInit
call, as mentioned in the second post. However, I can't seem to get an
AdaInit call to work. This is what I added to mydll.adb:
----
   procedure InitMe is
      procedure AdaInit;
      pragma Import (C, AdaInit);
   begin
      AdaInit;
   end InitMe;
---

I of course exported that procedure (InitMe) as well. However, when
compiling, I get an error: f:\shs\bugtest\mydll.adb:19: undefined
reference to `adainit'
Line 19 is of course my call to AdaInit.

Am I doing this correctly?
Also, do I need to import using C if I'll only be using this in an Ada
program? Can I do something like "Import (Ada, AdaInit)"? (This of
course doesn't solve the compile problem, I tried).




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 20:23         ` cybersaga
@ 2006-03-19 21:19           ` cybersaga
  2006-03-20  1:10             ` cybersaga
  0 siblings, 1 reply; 9+ messages in thread
From: cybersaga @ 2006-03-19 21:19 UTC (permalink / raw)


My guess is I'm not compiling this properly. What I have been doing is
just 'gnatmake -Pmydll', which uses the project file for all the
options and such.

What I have read is that gnatbind should be creating the procedures
'adainit' and 'adafinal', but from the error I'm getting, it apparantly
isn't.

How should I be compiling this DLL?




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: DLL Troubles
  2006-03-19 21:19           ` cybersaga
@ 2006-03-20  1:10             ` cybersaga
  0 siblings, 0 replies; 9+ messages in thread
From: cybersaga @ 2006-03-20  1:10 UTC (permalink / raw)


I finally got it working. Turns out I did have to compile it
differently:

gcc -c mydll.adb
gnatbind -n mydll
gcc -c b~mydll.adb
gcc -shared -o .\dll\mydll.dll mydll.o b~mydll.o
-LC:/GNAT/lib/gcc/pentium-mingw32msv/3.4.5/adalib/ -lgnat-GPL2005

If anyone can figure out how to do the same thing using the project
file, let me know.




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-03-20  1:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-19 18:46 DLL Troubles cybersaga
2006-03-19 19:22 ` tmoran
2006-03-19 19:27   ` cybersaga
2006-03-19 19:30     ` cybersaga
2006-03-19 20:13       ` Pascal Obry
2006-03-19 20:23         ` cybersaga
2006-03-19 21:19           ` cybersaga
2006-03-20  1:10             ` cybersaga
2006-03-19 19:37 ` Jeffrey R. Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox