Steve Sperber
asked on
Java Native methods giving "java.lang.UnsatisfiedLinkError" for matching parameters
I have created dll with C++ code successfully and put the dll in the jdk/bin folder in windows environment.
When I execute the native method it gives Runtime error
It is not due to mismatch of the parameters as I passed empty parameters and returned void (even then it gives this error).
When I execute the native method it gives Runtime error
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJNI.jgd_function()V
at TestJNI.jgd_function(Native Method)
at Test.jgd_function(FedExTest.java:12)
at main.main(main.java:5)
It is not due to mismatch of the parameters as I passed empty parameters and returned void (even then it gives this error).
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
The screenshots show a C method called jgdfunction whereas the stack trace indicates it was looking for jgd_function (note the UNDERSCORE). Could this be the issue?
ASKER
When I raised the question In the second posting I thought underscore in "jgd_function" could be an issue. I removed the underscore completely from every function and file the next time.
so that is unfortunately not the issue. So the stack trace remains.
Questons -
1) Is it necessary to register the dll by regsvr32 command followed by dll name. I assume not as I am putting the dll from where I am executing the java program i.e. "C:\Program Files (x86)\Java\jdk1.6.0_31\bin "
2) As the dll Library loads fine, What reflection APIs can be used to find out what methods parameter are expected for the native function.
3) attaching the native Wrapper C file that was generated (if that helps)
Test-wrap.c
so that is unfortunately not the issue. So the stack trace remains.
C:\Program Files (x86)\Java\jdk1.6.0_31\bin>java main
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJNI.jgdfunction(I)I
at TestJNI.jgdfunction(Native Method)
at Test.jgdfunction( Test.java:12)
at main.main(main.java:5)
Questons -
1) Is it necessary to register the dll by regsvr32 command followed by dll name. I assume not as I am putting the dll from where I am executing the java program i.e. "C:\Program Files (x86)\Java\jdk1.6.0_31\bin
2) As the dll Library loads fine, What reflection APIs can be used to find out what methods parameter are expected for the native function.
3) attaching the native Wrapper C file that was generated (if that helps)
Test-wrap.c
The '@8' is caused by a wrong calling convention then - try '__cdecl' to circuvent that, e.g.
extern "C" void __cdecl test();
Ooops, sorry, maybe a bit more 'portable':
extern "C" void WINAPIl test();
ASKER
I am using swig to compile the interface(".i" file) and c classes(".c" classes) and it does not allow to compile with suggested keywords before function names
//extern "C" void _cdecl jgdfunction(); //Error: Syntax error in input(1).
//extern "C" void WINAPIl test(); //Error: Syntax error in input(1).
extern "C" void jgdfunction(); // compiles without error
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Sara,
gcc uses C compiler by default and i use below commands to compile and generate dll so it should be "C" language and dll be c output
C:\Cplusplus\swigwin-2.0.1 1>gcc -c Test.c Test_wrap.c -I/C:/Installation/Java6/i nclude -I/C:/Installation/Java6/i nclude/win 32
C:\Cplusplus\swigwin-2.0.1 1>gcc -shared Test.o Test_wrap.o -o Test.dll
2) There is no ".def" files in the path.
3) I created the "Test.h" as you put it up and in the same directory I still get changed function name (as seen through dependency walker).
Now the root cause is how will the compiler know that Test.h is in the path. Do I have to include that in the commands or include that in "Test.c" or "Test.i" file.
The command that i use to generate the wrapper and c classes are:-
gcc uses C compiler by default and i use below commands to compile and generate dll so it should be "C" language and dll be c output
C:\Cplusplus\swigwin-2.0.1
C:\Cplusplus\swigwin-2.0.1
2) There is no ".def" files in the path.
3) I created the "Test.h" as you put it up and in the same directory I still get changed function name (as seen through dependency walker).
Java_TestJNI_jgdfunction@8
Now the root cause is how will the compiler know that Test.h is in the path. Do I have to include that in the commands or include that in "Test.c" or "Test.i" file.
The command that i use to generate the wrapper and c classes are:-
C:\Cplusplus\swigwin-2.0.11>swig -java Test.i
Based on SWIG Tutorial
I created the "Test.h" as you put it upyou need to compile the test.c with flag -D DLL_EXPORTS such that the __declspec(dllexports) becomes active. alternatively remove the statements regarding DLL_EXPORTS what doesn't matter as long as you don't want to include the header from a different c/c++ project.
//test.h
#define DLL_EXP __declspec(dllexport)
#ifdef __cplusplus
extern "C"
{
#endif
// declare exported function
int DLL_EXP jgdfunction(int);
// declare more functions if needed here
#ifdef __cplusplus
}
#endif
ASKER
Actually I realize that method signature is/may not be the issue as I compared with some well known dlls/APIs of Java and they show the same method signature issue through dependency walker. so it is some other issue.
I am planning to switch the IDE to Free Visual Studio Express Version to make and debug the dll for the native method calls.
I am planning to switch the IDE to Free Visual Studio Express Version to make and debug the dll for the native method calls.
ASKER
I've requested that this question be closed as follows:
Accepted answer: 0 points for jgdvishnu's comment #a39868013
for the following reason:
this is the only way out
Accepted answer: 0 points for jgdvishnu's comment #a39868013
for the following reason:
this is the only way out
Not ready to be closed yet. What's more people have helped to quite a large extent so to ignore that help by not awarding points shows a lack of gratitude
When you've got a proper solution, come back and tell people what it was and award points
When you've got a proper solution, come back and tell people what it was and award points
Agree with the non-closing request. Export by ordinal *is* an issue here.
Might also be worth checking for library dependencies
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I've requested that this question be closed as follows:
Accepted answer: 0 points for jgdvishnu's comment #a39870422
Assisted answer: 250 points for jkr's comment #a39869297
for the following reason:
Thanks to JKR and sarabande
Accepted answer: 0 points for jgdvishnu's comment #a39870422
Assisted answer: 250 points for jkr's comment #a39869297
for the following reason:
Thanks to JKR and sarabande
Thanks to JKR and sarabandeSo, if you want to thank Sarabande, then why did you not give her (him?) any points..?
@CEHJ: thanks, but it is quite ok that my comments did not get an assist if they didn't help to solve the issue.
Sara
Sara
ASKER
2) Dependency Walker shows change in function name slightly.
a) function with void parameter changed to function@8
b) function with int parameter changed to function@12
but Not sure if that is the issue.
3) Changes like these did not help much -
extern "C" {
int jgdfunction(int i);
};
Or
extern int fact(int n);
Still the stack trace looks like:-
C:\Program Files (x86)\Java\jdk1.6.0_31\bin
start Loading native method
End of loading native method
start Calling native method
Exception in thread "main" java.lang.UnsatisfiedLinkE
at TestJNI.jgdfunction(Native
at Test.jgdfunction( Test.java:12)
at NativeClient.main(NativeCl