Print

Print


Hello,

I have put together a binding for Java JNI.
Apart from a few things, such as looking up
the windows registry to locate the Java runtime,
I thought I had generated a portable 100% Ada
binding.

However, when I started to work on examples of
using the binding, I realised that although
the binding itself is portable, code using the
binding is not.

The problem is with Java calls to native code.
On most platforms these calls use the C convention.
However on Windows, the Stdcall convention is used.

Thus users of my binding need a different pragma
on windows to other platforms.
How can this be done without changing the code,
or having two versions of it?
If only I could rename conventions.
In C, this is accomplished with cpp using #defines
in a machine dependent header file.

Can anyone point me to a description of the Stdcall
convention so I can understand better how it differs
from C convention? ( I have some code that doesn't
seem to care which convention is used - but the
code below falls over with convention C)

Is there a good reason for windows libraries to not use
C convention?
Or is it just an accident of Microsoft history?

Although the Stdcall convention is not in the RM,
is it available with the same name with most Ada
compilers on windows?

Below is some code that registers a native method
with Java on windows. The Javelin JNI binding that
this code uses will be released under LGPL shortly.
First I have to solve this Stdcall issue and do some
more testing.

Thanks for any help.
Geoff




package Javelin_Demo is
   procedure Register_Natives;
end Javelin_Demo;

with Javelin.JNI;
with Interfaces.C.Strings;
with Ada.Text_IO;

package body Javelin_Demo is

   package JNI renames Javelin.JNI;
   package CS renames Interfaces.C.Strings;

   --  this function gets called from Java code
   function Msg (Env : JNI.JNI_Env_Access;
                 This : JNI.Jobject;
                 X : JNI.Jint
                ) return JNI.Jstring;
   pragma Convention (Stdcall, Msg);
   -------------------^^^^^^^-------------------------------
   --  needs to be Convention C on non windows platforms
   ---------------------------------------------------------
   ---------------------------------------------------------

   function Msg (Env : JNI.JNI_Env_Access;
                 This : JNI.Jobject;
                 X : JNI.Jint
                ) return JNI.Jstring
   is
   begin  --  Msg
      return JNI.New_String ("Welcome to Javelin => "
                             & JNI.Jint'Wide_Image (X));
   end Msg;



   procedure Register_Natives
   is
      Native_Methods : JNI.Arrayof_Native_Method (0 .. 0);
   begin
      Native_Methods (0).Name := CS.New_String ("msg");
      Native_Methods (0).Signature
        := CS.New_String ("(I)Ljava/lang/String;");
      Native_Methods (0).Fn_Ptr := Msg'Address;

      JNI.Register_Natives (JNI.Find_Class ("JavelinDemo"),
                            Native_Methods);
   end Register_Natives;

end Javelin_Demo;