Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / February 2006

Tip: Looking for answers? Try searching our database.

JNI problem: How to prevent VC++ compiler from doing name mangling

Thread view: 
abhijeet.s - 02 Feb 2006 06:40 GMT
Fews days back; I completed developement of a JNI module where in I
added support for few C++ native methods to be called from Java. For
those methods native method call succeeds from Java sample program ; it
works till date; But for new methods that I added into module today it
gives me java.lang.UnsatisfiedLinkError.

I used dependency viewer & I tried to find out mangled names; all
functions have something '@X' some number in the end even old methods
too!. After reading so many articles I came to know that it should be
problem with C++ compiler doing some dirty work (name mangling).
somehwhere I got the answer also; advised me to use extern "C" to
prevent that. But to my surprise, .h generated by javah -jni, contains
black extern "C". It means that compiler should not mangle the names;
but doing it!

I haven't understand 2 things. If this had been a problem of name
mangling by C++ compiler, I would have not able to call any of the
method; but call succeeds for old ones. How come?
Any other way how to prevent "MS" stupid compiler from doing this.

Any help on this will really be appriciated.

Regards
Abhijeet
Alan Krueger - 02 Feb 2006 06:56 GMT
> I used dependency viewer & I tried to find out mangled names; all
> functions have something '@X' some number in the end even old methods
> too!. After reading so many articles I came to know that it should be
> problem with C++ compiler doing some dirty work (name mangling).

Actually, the C++ compiler does much worse than add @NNN at the end of
method names.  See the following for details on the @NNN:

http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_Microsoft_Windows
abhijeet.s - 02 Feb 2006 07:38 GMT
Could you do it for me on this:

JNIEXPORT jfloat JNICALL Java_Functions_getattrfloat  (JNIEnv *,
jobject, jstring, jstring);

Regards
Abhijeet
Chris Uppal - 02 Feb 2006 10:01 GMT
> Fews days back; I completed developement of a JNI module where in I
> added support for few C++ native methods to be called from Java. For
[quoted text clipped - 10 lines]
> black extern "C". It means that compiler should not mangle the names;
> but doing it!

Not quite.  Even 'C' compilation/linkage can do /some/ name mangling.  Exactly
what depends on whether you are using the "__stdcall" or "__cdecl" calling
convention, I believe (but I'm not sure of the details).

As far as I can see from checking a small JNI DLL that I had lying around, the
"correct" compilation options (which were just the defaults) plus the stuff
generated by javah, results in a DLL with names decorated as you describe.  So
I think your compilation is probably OK, but that something else is going wrong
somewhere (finding an old copy of the DLL(s) perhaps ?).

It is possible to control what names appear in the DLL by using a .def file,
but I don't believe that would work here (although its a very good idea for
general-purpose DLLs) since the JVM will work out what names to look for and it
will be looking for names with the @X decoration.

   -- chris
abhijeet.s - 03 Feb 2006 05:54 GMT
same problem but with more description....................
source pasted....

Pls help me out.

Fews days back; I completed developement of a JNI module where in I
added support for few C++ native methods to be called from Java. For
those methods native method call succeeds from Java sample program ; it

works till date; But for new methods that I added into module today it
gives me java.lang.UnsatisfiedLinkError.

I used dependency viewer & I tried to find out mangled names; all
functions have something '@X' some number in the end even old methods
too!. After reading so many articles I came to know that it should be
problem with C++ compiler doing some dirty work (name mangling).
somehwhere I got the answer also; advised me to use extern "C" to
prevent that. But to my surprise, .h generated by javah -jni, contains
black extern "C". It means that compiler should not mangle the names;
but doing it! one of the functions that i added earliier "getattrnum"
works fine as explained below.

call to "getattrfloat" gives me unsatisfiedlink error.

I haven't understood 2 things. If this had been a problem of name
mangling by C++ compiler, I would have not able to call any of the
method; but call succeeds for old ones. How come?
Any other way how to prevent "MS" stupid compiler from doing this.

//java file

public class LamiaFunctions{
  public void callback(String msg){
              System.out.println(msg);
      }

  public LamiaFunctions(){
      }
public native synchronized float getattrfloat(String path,String name);
public native synchronized int getattrnum(String path,String name);

  public native synchronized void stop();
      static
      {
              System.loadLibrary("SimulatorJniWrapper");
      }
}

//java jni app program

import java.io.*;
import java.math.*;

public class Taz
{
      public static void main(String[] main_args)
      {
              LamiaFunctions fnLamia = new LamiaFunctions();
              fnLamia.start();
              try
              {
                      Thread.sleep(1000);
              }
              catch (InterruptedException ie)
              {
                      ie.printStackTrace();
              }

              try
              {
                      if(fnLamia.iscnf() == 1)
                      {
                              System.out.println("Already loaded");
                      }
                      else
                      {
                              fnLamia.loadcnf("3xSAIVL.xml");
                      }

                      System.out.println("Configuration File:
"+fnLamia.getcnf());
//below call succeeds : getattrnum
                      int i = fnLamia.getattrnum("Gas Type");
                      System.out.println(i);
                      System.out.println("\n");

//now this call fails getattrfloat, this function newly added into
native
                      float f = fnLamia.getattrfloat"Max Temp");
                      System.out.println(f);
                      System.out.println("\n");
                      fnLamia.stop();
              }
              catch(Exception ex)
              {
                      System.out.println("Exception: " + ex);
              }
      }
}

// cpp functions declarations & definitions in
SimulatorJniWrapper.cpp

JNIEXPORT jint JNICALL Java_LamiaFunctions_getattrnum
(JNIEnv *_jnienv, jobject _jobj, jstring _jpath, jstring _jattr)
{
return 1;
}

JNIEXPORT jfloat JNICALL Java_LamiaFunctions_getattrfloat
(JNIEnv *_jnienv, jobject _jobj, jstring _jpath, jstring _jname)
{
return 1.0
}

I am not able to figure out why call to first method succeeds & fails
on another.

C++ name mangled as follows:

_Java_LamiaFunctions_getattrfloat@16
_Java_LamiaFunctions_getattrnum@16

You happened to mention somewhere in your posting that use compiler
options to prevent c++ name mangling. what are those options for vc++
6.0

Any help on this will really be appriciated.

Regards
Abhijeet
Jean-Francois Briere - 03 Feb 2006 07:22 GMT
This should work on VC++ 6.0.

Go in 'Project Settings', 'C/C++' panel, 'Code Generation' category,
'Calling Convention' combobox:
The setting must be set to : '__cdelc' .

Also be sure that the  SimulatorJniWrapper.h file (that you didn't
show) has the following:

-----------------------------------------------------------------------------------------------------------------

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jfloat JNICALL Java_LamiaFunctions_getattrfloat
   (JNIEnv *_jnienv, jobject _jobj, jstring _jpath, jstring _jname);

JNIEXPORT jint JNICALL Java_LamiaFunctions_getattrnum
   (JNIEnv *_jnienv, jobject _jobj, jstring _jpath, jstring _jattr);

#ifdef __cplusplus
}
#endif

-----------------------------------------------------------------------------------------------------------------

Regards
Chris Uppal - 03 Feb 2006 09:48 GMT
> Go in 'Project Settings', 'C/C++' panel, 'Code Generation' category,
> 'Calling Convention' combobox:
> The setting must be set to : '__cdelc' .

Shouldn't make any difference to this issue, since "JNICALL" expands out to
__stdcall.

Of course, changing the option will affect other things...

   -- chris
Chris Uppal - 03 Feb 2006 11:46 GMT
> I am not able to figure out why call to first method succeeds & fails
> on another.
[quoted text clipped - 3 lines]
> _Java_LamiaFunctions_getattrfloat@16
> _Java_LamiaFunctions_getattrnum@16

You didn't /read/ my post.  Name mangling is not causing your problem.

(Incidentally, I've been checking and it appears that the function lookup code
in the JVM will first look for the properly decorated name
   _Java_LamiaFunctions_getattrfloat@16
and, if that fails, will fallback to trying the undecorated version
   Java_LamiaFunctions_getattrfloat
That's specific to Windows DLLs of course, but similar logic seems to be used
for other OSes.)

   -- chris
Jean-Francois Briere - 03 Feb 2006 20:32 GMT
Just for fun I tried your sample code with JDK 1.5 and VC++ 6.0 and it
works fine.

Regards


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.