Subject: Re: B19 dll with JNI causing Dr. Watson to drop by...
From: [email-masked] (Andrew Mickish)

19 Oct 1998 21:29:47 -0700
Message-ID: <[email-masked]>
References: <Pine.SUN.3.96.981018233313.504D-100000@theory>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
To: "Kiyoko F. Aoki" <[email-masked]>
Cc: [email-masked]

> Kiyoko F. Aoki wrote:
>
>   Hello all,
>
>   This is my second message to the mailing list regarding a problem I've
>   been trying to deal with for the past couple of weeks...  I hope someone
>   will be able to help out.
>
>   I am using g++ version egcs-2.91.57 (1.1 release) on NT4 (SP3) to create a
>   dll that is called from my Java program through JNI.  My problem is that
>   my Java app can call the C++ routine ok, but Dr. Watson pops up in the
>   following cases:
>
>   1. Initializing anything with new or malloc
>   2. Calling another c++ routine that allocates any memory as in above
>
>   I was told that perhaps I wasn't initializing my dll correctly?  What
>   would that entail??  I created the (relocatable) dll using the procedures
>   from cygnus' home page...  any suggestions would be greatly appreciated!
>
>   Kiyoko
>
>   ------------------------------------------------------------------------
>   Kiyoko F. Aoki          Research Assistant              Academia Sinica
>   ------------------------------------------------------------------------
>
Kiyoko,

It is significantly more difficult to produce JNI-friendly DLL's with gcc than
with VC++.  I do not fully understand the issues involved, and I hope a future
generation of cygwin gcc addresses this usability issue.

Attached is the sequence of steps that I use to compile my JNI DLL's.  I did a
quick search of my C++ source code and was surprised to find that indeed I do
not malloc or new any native memory, though I do make JNI malloc calls like
NewObject and NewStringUTF.

Hope this helps,

--Andrew Mickish
  http://www.andrew.cmu.edu/~am2q/

_______________________ forwarded message _____________________

Subject:  Java JNI with GNU-WIN32 gcc
   Date:   Thu, 11 Jun 1998 19:48:11 -0400
   From:  Andrew Mickish <[email-masked]>
     To:    [email-masked]

With significant help from Bill Pringlemeir, I figured out how to compile
Sun's JNI tutorial HelloWorld example under GNU-WIN32 with gcc.  I will keep a
ZIP file of the gcc-compatible code at
http://www.andrew.cmu.edu/~am2q/HelloWorld.zip for future reference.

Please add this information to the GNU-WIN32 documentation and FAQ.  As of
version 19.1, it is significantly more complicated to compile a
Java-compatible DLL under gcc than under Microsoft Visual C++.  Even printf()
does not work in a gcc-compiled DLL, even thoough it works fine with VC++.
Will this be changing with future releases of GNU-WIN32?

Here are a few hints for how to compile a trivial JNI-compaible DLL with gcc:

1)  You need init.cc, an element of building relocatable DLLs

2)  There is a complicated linking procedure involving ld and intermediate
files:

     ld --base-file hello.base --dll -o hello.dll HelloWorldImp.o init.o
          $(LIB) -e _dll_entry@12
     dlltool --as=as --dllname hello.dll --def hello.def --base-file
          hello.base --output-exp hello.exp
     ld --base-file hello.base hello.exp --dll -o hello.dll HelloWorldImp.o
          init.o $(LIB) -e _dll_entry@12
     dlltool --as=as --dllname hello.dll --def hello.def --base-file
          hello.base --output-exp hello.exp
     ld hello.exp --dll -o hello.dll HelloWorldImp.o init.o $(LIB)
          -e _dll_entry@12

3)  Printf will not work here.  Use a Windows dialog box or call back into
     Java to invoke System.out.println():

    void jprintf (JNIEnv *env, char* str) {

      jstring jstr = (*env)->NewStringUTF(env, str);
      jclass System_class = (*env)->FindClass(env, "java/lang/System");
      jfieldID fid_out = (*env)->GetStaticFieldID(env, System_class, "out",
           "Ljava/io/PrintStream;");
      jobject out = (*env)->GetStaticObjectField(env, System_class, fid_out);
      jclass PrintStream_class = (*env)->FindClass(env,
           "java/io/PrintStream");
      jmethodID mid_println = (*env)->GetMethodID(env, PrintStream_class,
           "println", "(Ljava/lang/String;)V");
      if (mid_println == 0) {
        exit(1);
      }
      (*env)->CallVoidMethod(env, out, mid_println, jstr);
    }

    JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
    (JNIEnv *env, jobject obj)
    {
      (void)env; (void)obj;
      MessageBoxA(NULL,"Hello Jupiter!", "Hello world!", 0);
      jprintf(env, "Hello Uranus!\n");
      return;
    }

A collection of files that implement Sun's JNI HelloWorld example may be found
at http://www.andrew.cmu.edu/~am2q/HelloWorld.zip

--Andrew Mickish
  [email-masked]

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".