Omgili, forum search, forums search, search forums, discussion search,discussions search, search discussions, board search, boards search, search boards
  Advanced Search

Creating a dll in cygwin for use with jni without -mno-cygwin

On Wed, 8 Aug 2007 13:12:18 -0700 (PDT), robbincatz <...@gmail.com> wrote:

I am trying to create a dll in cygwin for use with jni. I have successfully
achieved this for a simple "hello world" type program using the following
command:

gcc -mno-cygwin -Wl,--add-stdcall-alias -shared -o myDll.dll myNativeCode.c

However I would like to create my dll without using the -mno-cygwin option
as my c code relies on additional C libraries which when included causes the
above command to produce a large number of errors involving the libraries I
am using:

/usr/local/lib/libpbc.a(libpbc_la-pairing.o): In function
`pairing_init_inp_gene
ric':
/home/me/pbc_build/pbc-0.4.11/ecc/pairing.c:80: undefined reference to
`___asse
rt'
/home/me/pbc_build/pbc-0.4.11/ecc/pairing.c:81: undefined reference to
`___asse
rt'
/home/me/pbc_build/pbc-0.4.11/ecc/pairing.c:147: undefined reference to
`___get
reent'
/usr/local/lib/libpbc.a(libpbc_la-pairing.o): In function
`pairing_init_inp_buf'
.
.
.
.
.
.
/usr/local/lib/libgmp.a(assert.o):assert.c:(.text+0x29): undefined reference
to
`___getreent'
/usr/local/lib/libgmp.a(assert.o):assert.c:(.text+0x4b): undefined reference
to
`___getreent'
/usr/local/lib/libgmp.a(assert.o):assert.c:(.text+0x98): undefined reference
to
`___getreent'
/usr/local/lib/libgmp.a(doprntf.o):doprntf.c:(.text+0x483): undefined
reference
to `__imp___ctype_'
collect2: ld returned 1 exit status

( I have just given the start and end of the errors produced )

I have looked at every bit of information on -mno-cygwin, building dlls in
cygwin and jni but nothing has helped although I now believe the problem
lies with the fact that i did not install my libraries for mingw but for
cygwin.

If I could create my dll without the -mno-cygwin option I think it would
solve my problem, I have tried with no success to do this. When I try this
everything appears to be fine ( i.e. I receive no error messages ) but when
I run my java code ( which calls the native c code ) it hangs, this happens
even for the most basic "hello world" ap.

My code is as follows:

main.java:

public class main
{
static
{
System.loadLibrary( "theNativeMethod" );
}

public static void main( String args[] )
{
AClassWithNativeMethods c = new AClassWithNativeMethods();
c.theNativeMethod();
}
}


AClassWithNativeMethods.java:

public class AClassWithNativeMethods
{
public native void theNativeMethod();

public void aJavaMethod()
{
theNativeMethod();
}
}

AClassWithNativeMethods.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class AClassWithNativeMethods */

#ifndef _Included_AClassWithNativeMethods
#define _Included_AClassWithNativeMethods
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: AClassWithNativeMethods
* Method: theNativeMethod
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_AClassWithNativeMethods_theNativeMethod
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

theNativeMethod.c:

#include <stdio.h>
#include "AClassWithNativeMethods.h"

JNIEXPORT void JNICALL Java_AClassWithNativeMethods_theNativeMethod( JNIEnv*
env, jobject thisObj )
{
printf( "Hello JNI World\n" );
}

I used the following to compile and run my java code:
javac AClassWithNativeMethods.java main.java
javah -jni AClassWithNativeMethods
java main

I would really appreciate any help in producing a dll which works and doesnt
use the -mno-cygwin option. Or any other suggestions

Thanks

:)
--
View this message in context: http://www.nabble.com/Creating-a-dll-in-cygwin-for-use-with-jni-without--mno-cy gwin-tf4238762.html#a12060945
Sent from the Cygwin Users mailing list archive at Nabble.com.

--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/



On Wed, 08 Aug 2007 13:52:55 -0700, Brian Dessent <...@dessent.net> wrote:

robbincatz wrote:

> I have looked at every bit of information on -mno-cygwin, building dlls in
> cygwin and jni but nothing has helped although I now believe the problem
> lies with the fact that i did not install my libraries for mingw but for
> cygwin.

Using -mno-cygwin makes a MinGW application/DLL. It is the same as
using the MinGW gcc. You can't link together MinGW libraries and Cygwin
libraries into the same output, so you would need a MinGW version of
every library that your application links to in order to use
-mno-cygwin.

> If I could create my dll without the -mno-cygwin option I think it would
> solve my problem, I have tried with no success to do this. When I try this
> everything appears to be fine ( i.e. I receive no error messages ) but when
> I run my java code ( which calls the native c code ) it hangs, this happens
> even for the most basic "hello world" ap.

The problem here is that you're loading the Cygwin1.dll library
dynamically, as opposed to linking against it normally. Special steps
are required to do this because the Cygwin library has special
initialization needs to set up the TLS area at the bottom of the stack
for its signal emulation. This is handled automatically by the crt
startup objects in a normal Cygwin binary, but when you just call
LoadLibrary in a non-Cygwin application you have to handle it yourself.

This is covered in the FAQ:
<http://cygwin.com/faq/faq.programming.html#faq.programming.msvs-mingw>.
The best reference to how to do this is the cygload.cc example in the
testsuite.

I have no idea how you'd handle this stack requirement in a java
application, other than writing your own initialization procedure that
saves a copy of the bottom 4k, initializes Cygwin, and then restores the
saved parts. However for this to work (as opposed to the other strategy
of making sure that the 4k is actually reserved as early in the
initialization process as possible) it means your cleanup/deinit code
has to be run before the stack gets unwound down to that part of it that
you smashed away.

Brian

--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/

On Sun, 25 Nov 2007 15:01:17 -0800 (PST), Martin Dorey <...@bluearc.com> wrote:

> The problem here is that you're loading the Cygwin1.dll library
> dynamically, as opposed to linking against it normally.

(Depending on exactly what you're trying to do, another approach can be to
use a Cygwin-based executable to launch Java. There's more information
about how to do that, including actively maintained source code, at
http://elliotth.blogspot.com/2005/08/porting-jni-code-to-win32-with-cygwin.html .)

--
View this message in context: http://www.nabble.com/Creating-a-dll-in-cygwin-for-use-with-jni-without--mno-cy gwin-tf4238762.html#a13941128
Sent from the Cygwin list mailing list archive at Nabble.com.

--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/

On Wed, 08 Aug 2007 14:33:25 -0700, Brian Dessent <...@dessent.net> wrote:

Brian Dessent wrote:

> [...] your own initialization procedure that
> saves a copy of the bottom 4k, initializes Cygwin, and then restores the
> saved parts.

Just to be clear, I don't mean that it should initialize Cygwin and then
restore those parts of the stack.

To put it differently, when Cygwin initializes it expects to have free
reign of the bottom X bytes of the stack for its own use. You can
accomplish this two ways:

The designed way - have code that runs very early in the sequence of
process initialization that simply allocates these bytes on the stack
like a standard C auto variable, and since the stack is nearly empty
they will be at the bottom. This is what the Cygwin startup code
(crt0.o) does when you run a Cygwin binary, and how it is designed to
work.

The "fake it" way - Assume that you want to load the Cygwin DLL
dynamically at runtime, and the stack has already been robustly
allocated/populated by whatever application is already running. You
have no control over the bottom X bytes, so you're kind of screwed. The
best you can hope to do is make a copy of those X bytes, then initialize
Cygwin (which now "owns" that area and will overwrite whatever's there
with its own data) and hope that the control flow of the application is
such that you will be able to unload the Cygwin DLL and restore those
saved bytes before program flow reaches a point where the stack gets
unwound down to that earliest frame.

If you don't take care of the deinitialization and restoration part then
everything will seem right but your application will probably crash and
die horribly when it terminates.

Obviously the key here is that you need to run this initialization code
as early in the process init as possible. If I recall right the cygload
code tries to do this right at the beginning of main() and at that point
there is only a small amount of data at the bottom of the stack to
save/restore, which also means the best chances of that data not being
referenced/used before it is restored.

[ X is sizeof(_cygtls) which has traditionally been less than 4K so 4K
is a nice round number but the current cygload actually uses 32k for a
safety margin, so the docs should be updated. ]

Brian

--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/

On Thu, 9 Aug 2007 08:45:30 -0700 (PDT), robbincatz <...@gmail.com> wrote:

I really appreciate your detailed reply Brian. Having read your response I
realised that creating a dll in cygwin is way over my head especially as I
am limited on how much (more)time I can spend on this problem. I have since
switched to using a linux platform and am having much more success.

Thanks a million

:)

Brian Dessent wrote:
>
> Brian Dessent wrote:
>
>> [...] your own initialization procedure that
>> saves a copy of the bottom 4k, initializes Cygwin, and then restores the
>> saved parts.
>
> Just to be clear, I don't mean that it should initialize Cygwin and then
> restore those parts of the stack.
>
> To put it differently, when Cygwin initializes it expects to have free
> reign of the bottom X bytes of the stack for its own use. You can
> accomplish this two ways:
>
> The designed way - have code that runs very early in the sequence of
> process initialization that simply allocates these bytes on the stack
> like a standard C auto variable, and since the stack is nearly empty
> they will be at the bottom. This is what the Cygwin startup code
> (crt0.o) does when you run a Cygwin binary, and how it is designed to
> work.
>
> The "fake it" way - Assume that you want to load the Cygwin DLL
> dynamically at runtime, and the stack has already been robustly
> allocated/populated by whatever application is already running. You
> have no control over the bottom X bytes, so you're kind of screwed. The
> best you can hope to do is make a copy of those X bytes, then initialize
> Cygwin (which now "owns" that area and will overwrite whatever's there
> with its own data) and hope that the control flow of the application is
> such that you will be able to unload the Cygwin DLL and restore those
> saved bytes before program flow reaches a point where the stack gets
> unwound down to that earliest frame.
>
> If you don't take care of the deinitialization and restoration part then
> everything will seem right but your application will probably crash and
> die horribly when it terminates.
>
> Obviously the key here is that you need to run this initialization code
> as early in the process init as possible. If I recall right the cygload
> code tries to do this right at the beginning of main() and at that point
> there is only a small amount of data at the bottom of the stack to
> save/restore, which also means the best chances of that data not being
> referenced/used before it is restored.
>
> [ X is sizeof(_cygtls) which has traditionally been less than 4K so 4K
> is a nice round number but the current cygload actually uses 32k for a
> safety margin, so the docs should be updated. ]
>
> Brian
>
> --
> Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
> Problem reports: http://cygwin.com/problems.html
> Documentation: http://cygwin.com/docs.html
> FAQ: http://cygwin.com/faq/
>
>
>

--
View this message in context: http://www.nabble.com/Creating-a-dll-in-cygwin-for-use-with-jni-without--mno-cy gwin-tf4238762.html#a12074866
Sent from the Cygwin Users mailing list archive at Nabble.com.

--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/