Skip to content

Instantly share code, notes, and snippets.

@ssfang
Last active December 25, 2017 08:32
Show Gist options
  • Save ssfang/e52c00cd446081cd72a982a2dd8634d4 to your computer and use it in GitHub Desktop.
Save ssfang/e52c00cd446081cd72a982a2dd8634d4 to your computer and use it in GitHub Desktop.
cygwin vs mingw gcc and jni
  • Local Reference And Local Frame

IBM: Overview of JNI object references JNI Local Reference Changes in ICS

  • NewObjectA
extern "C" {
/*
 * The version NewObject method just accept the parameters of the constructor of ctor_mid
 * must be java object types. e.g. class JavaToy{ JavaToy(Integer price, String name){}}
 *
 * JavaMethod: native static <T> T NewObject(Class<T> clazz, long method, Object ...params);
 * Class:     JnToy
 * Method:    NewObject
 * Signature: (Ljava/lang/Class;J[Ljava/lang/Object;)Ljava/lang/Object;
 **/
JNIEXPORT jobject JNICALL Java_JnToy_NewObject(JNIEnv *env, jclass UNUSED(thiz),
                                               jclass clazz, jlong ctor_mid,
                                               jobjectArray params) {
  jvalue *args = NULL;
  jobject ret;
  if (NULL != params) {
    jsize arrayLength = env->GetArrayLength(params);
    args = (jvalue*) alloca(arrayLength * sizeof(jvalue));
    // No need to check on the ArrayIndexOutOfBoundsException, since it won't happen here.
    for (jsize index = 0; index < arrayLength; ++index) {
      jobject jobj = env->GetObjectArrayElement(params, index);
      args[index].l = jobj;
    }
    //ret = env->NewObjectA(clazz, (jmethodID) ctor_mid, args);
    //for (jsize index = 0; index < arrayLength; ++index) {
    //  env->DeleteLocalRef(args[index].l);
    //}
  }//else{
    ret = env->NewObjectA(clazz, (jmethodID) ctor_mid, args);
  //}
  return ret;
}

}

jni with cygwin gcc

C:\Java\jdk1.8.0_40\include\win32/jni_md.h:35:11: error: '__int64' does not name a type
   typedef __int64 jlong;
           ^
In file included from ../jni/JnToy.h:2:0,
                 from ../jni/JnToy.cpp:9:
C:\Java\jdk1.8.0_40\include/jni.h:126:5: error: 'jlong' does not name a type
     jlong    j;

GCC中没有 __int64,解决方法: 一种添加 编译命令中添加-D__int64="long long",另一种是修改${JAVA_HOME}/include/win32/jni_md.h

GCC doesn't have a __int64 built-in, and this patch basically uses "long long" instead.

  • Add -D__int64="long long" to the command to compile.
  • Or edit the file /include/win32/jni_md.h, Where is the installation root (eg., c:/jdk1.4.2). 将下面语句(Replace the segment):
typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;

替换为(with):

typedef long jint;
#ifdef __GNUC__
typedef long long jlong;
#else
typedef __int64 jlong;
#endif
typedef signed char jbyte;

完整的:

/*
 * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_

#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall

/* [JNI Types and Data Structures](http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp9502) */
/* https://android.googlesource.com/platform/libnativehelper/+/master/include/nativehelper/jni.h */

#include <stdint.h>
/* Primitive types that match up with Java equivalents. */
typedef uint8_t  jboolean; /* unsigned 8 bits */
typedef int8_t   jbyte   ; /* signed 8 bits */
typedef uint16_t jchar   ; /* unsigned 16 bits */
typedef int16_t  jshort  ; /* signed 16 bits */
typedef int32_t  jint    ; /* signed 32 bits */
typedef int64_t  jlong   ; /* signed 64 bits */
typedef float    jfloat  ; /* 32-bit IEEE 754 */
typedef double   jdouble ; /* 64-bit IEEE 754 */

// Explicitly assert the consistency and correctness of mapping Java Primitive types to native C types.
union __verify_primitive_types_against_java_peer_types
{
	char  int8_t_eq_jboolean[1 == sizeof(jboolean) ? 1 : -1];
	char  int8_t_eq_jbyte   [1 == sizeof(jbyte   ) ? 1 : -1];
	char int16_t_eq_jchar   [2 == sizeof(jchar   ) ? 1 : -1];
	char int16_t_eq_jshort  [2 == sizeof(jshort  ) ? 1 : -1];
	char int32_t_eq_jint    [4 == sizeof(jint    ) ? 1 : -1];
	char int64_t_eq_jlong   [8 == sizeof(jlong   ) ? 1 : -1];
	char   float_eq_jfloat  [4 == sizeof(jfloat  ) ? 1 : -1];
	char  double_eq_jdouble [8 == sizeof(jdouble ) ? 1 : -1];
};

#endif /* !_JAVASOFT_JNI_MD_H_ */

Compile and Link the .dll file

Call the compiler:

gcc -D __int64="long long" -Wl,--kill-at -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp
nm JnToy.dll | grep parse # 查看函数名字,第二列带有T表示函数已定义。
objdump -p JnToy.dll | grep "DLL Name" # 检查依赖

The compiler options used are:

  • -Wl: The -Wl to pass linker option --add-stdcall-alias to prevent UnsatisfiedLinkError (symbols with a stdcall suffix (@nn) will be exported as-is and also with the suffix stripped). (Some people suggested to use -Wl,--kill-at.) (See also Options for Linking)

    • -Wl,--add-stdcall-alias 生成2个函数声明,一个是带@的 一个是不带@的
    • -Wl,--kill-at 不带@的函数声明
  • The -mno-cygwin option, enables building DLLs that have no dependencies on Cygwin own libraries and thus can be executed on machines which do not have Cygwin installed. 这个对早期版本cygwin的gcc(gcc-3)有效,现在这个选项废弃了,不可识别,不依赖Cygwin的dll需要使用Mingw的gcc。

  • The -Wl,--add-stdcall-alias passes the --add-stdcall-alias option to the linker; without it, the resulting application would fail with the UnsatisfiedLinkError.

  • The -shared option tells the compiler to generate a DLL ( not an executable file).

  • -m32 tells the compiler to create a 32-bit binary. On 64-bit systems the compiled binaries are 64-bit by default , which causes a lot of problems with 32-bit JDKs.

JNI-MinGW-DLL Posted August 10th, 2008 by fhackenberger JNI is the Java Native Interface, you will need to download and install the Java SDK. Note the installation directory (ie/ c:\j2sdk1.4.1_02 ) for use later. If you are using MSYS add a line similiar to the following in /etc/fstab and then restart MSYS:

c:/j2sdk1.4.1_02      /java

In MSYS the JNI DLL can be generated using the following (NOTE: -Wl has an 'L' not a '1'):

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at   -I/java/include -I/java/include/win32   -shared -o JavaImp.dll 
someJavaImp.c

In a standard command console it can be generated as follows (one continuous line):

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at
  -Ic:/j2sdk1.4.1_02/include -Ic:/j2sdk1.4.1_02/include/win32
  -shared someJavaImp.c -o JavaImp.dll

Where JavaImp.dll should be named whatever you refer to the library as in your .java file. To use the above dll you would refer to it as follows in your java classes code:

System.loadLibrary( "JavaImp" );

If you encounter problems ensure your CLASS_PATH and PATH are set appropriately for your environment. Please refer to Java Native Interface for further details on using a JNI DLL in java code.

#pragma comment(linker, "/EXPORT:func1=_func1@4")

ld

GNU ld has many options regarding DLLs, but we shall only focus on four (help information follows):

  • --add-stdcall-alias Export symbols with and without @nn
  • --kill-at Remove @nn from exported symbols
  • --out-implib Generate import library
  • --output-def Generate a .DEF file for the built DLL

Either gcc or ld can accept a DEF file directly on the command line. When we have the following line in the EXPORTS section,

TestFunction = TestFunction@4

both symbols will be exported to the DLL. This behaviour is different from dllwrap, which we shall talk of immediately.

__cdecl和__stdcall函数命名修饰

Stdcall and DLL tools of MSVC and MinGW

  • __cdecl函数有一个下划线前缀,
  • __stdcall函数不仅有一个下划线前缀而且还跟有一个@开头的参数列表字节数后缀。

如:double __cdecl sin(double)为_sin,double __stdcall sin(double)为_sin@8

how different compilers decorate __cdecl vs __stdcall differently:

                  MSVC DLL
Call Convention | (dllexport) | DMC DLL     | MinGW DLL  | BCC DLL
----------------------------------------------------------------------------
__stdcall       | _Function@n | _Function@n | Function@n | Function
__cdecl         | Function    | Function    | Function   | _Function

java.lang.UnsatisfiedLinkError

  • Exception in thread "main" java.lang.UnsatisfiedLinkError: no JnToy in java.library.path

    To add for VM Arguments: -Djava.library.path=lib

  • Exception in thread "main" java.lang.UnsatisfiedLinkError: JnToy.parseBytes([B)I

fangss@fangss-PC /cygdrive/c/Users/fangss/workspace/JToy/jni
$ nm JnToy.dll | grep parse
000000046ec91090 T Java_JnToy_parseBytes

fangss@fangss-PC /cygdrive/c/Users/fangss/workspace/JToy/jni
$ objdump -p JnToy.dll | grep "DLL Name"                                                
        DLL Name: cygwin1.dll
        DLL Name: KERNEL32.dll
  • Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\fangss\workspace\JToy\lib\JnToy.dll: Can't load AMD 64-bit .dll on a IA 32-bit platform
fangss@fangss-PC /cygdrive/c/Users/fangss/workspace/JToy/jni
$ file JnToy.dll
JnToy.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows

而,以下代码

  static {
    String lib_path = System.getProperty("java.library.path");
    System.out.println("java.library.path = " + lib_path);
    System.out.println("os.arch = " + System.getProperty("os.arch"));

    // java -version
    // Sun has a Java System property to determine the bitness of the JVM: 32 or 64:
    // http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_detection
    // the system property sun.arch.data.model has the value "32", "64", or "unknown"
    // sun.arch.data.model=32 // 32 bit JVM
    // sun.arch.data.model=64 // 64 bit JVM
    System.out.println("sun.arch.data.model = " + System.getProperty("sun.arch.data.model"));

    try {
      // JToy.dll (Windows) or libJToy.so (Unixes)
      System.loadLibrary("JnToy"); // Notice lack of lib prefix
    } catch (UnsatisfiedLinkError e) {
      e.printStackTrace();
    }
  }

输出为

java.library.path=lib
x86
32

表示,需要32位的dll。

安装

fangss@fangss-PC ~
$ explorer `cygpath -w /usr/local/bin`

fangss@fangss-PC ~
$ cygcheck -c bash binutils bzip2 cygwin gcc-core gcc-g++ gcc-java gzip m4 make unzip zip
Cygwin Package Information
Package              Version        Status
bash                 4.3.42-4       OK
binutils             2.25-4         OK
bzip2                1.0.6-2        OK
cygwin               2.4.1-1        OK
gcc-core             5.3.0-3        OK
gcc-g++              5.3.0-3        OK
gzip                 1.6-1          OK
m4                   1.4.17-2       OK

fangss@fangss-PC ~
$ type gcc
gcc 是 /usr/bin/gcc

fangss@fangss-PC ~
$ which gcc
/usr/bin/gcc

fangss@fangss-PC ~
$ whereis gcc
gcc: /usr/bin/gcc.exe /usr/lib/gcc /usr/share/man/man1/gcc.1.gz

  • 下载安装MinGW,安装后路径,已经添加到系统PATH之一的/bin/下了
fangss@fangss-PC ~
$ ls -l /bin/*gcc*
-rwxr-xr-x 1 fangss None   6707 一月  6 2010 /bin/colorgcc
-rwxr-xr-x 1 fangss None  71187 二月 27 15:37 /bin/cyggcc_s-seh-1.dll
-rwxr-xr-x 3 fangss None 815123 二月 27 15:40 /bin/gcc.exe
-rwxr-xr-x 2 fangss None  26643 二月 27 15:40 /bin/gcc-ar.exe
-rwxr-xr-x 2 fangss None  26643 二月 27 15:40 /bin/gcc-nm.exe
-rwxr-xr-x 2 fangss None  26643 二月 27 15:40 /bin/gcc-ranlib.exe
-rwxr-xr-x 2 fangss None 845843 六月 16 2015 /bin/i686-w64-mingw32-gcc.exe
-rwxr-xr-x 2 fangss None 845843 六月 16 2015 /bin/i686-w64-mingw32-gcc-4.9.2.exe
-rwxr-xr-x 1 fangss None  26131 六月 16 2015 /bin/i686-w64-mingw32-gcc-ar.exe
-rwxr-xr-x 1 fangss None  26131 六月 16 2015 /bin/i686-w64-mingw32-gcc-nm.exe
-rwxr-xr-x 1 fangss None  26131 六月 16 2015 /bin/i686-w64-mingw32-gcc-ranlib.exe
-rwxr-xr-x 3 fangss None 815123 二月 27 15:40 /bin/x86_64-pc-cygwin-gcc.exe
-rwxr-xr-x 3 fangss None 815123 二月 27 15:40 /bin/x86_64-pc-cygwin-gcc-5.3.0.exe
-rwxr-xr-x 2 fangss None  26643 二月 27 15:40 /bin/x86_64-pc-cygwin-gcc-ar.exe
-rwxr-xr-x 2 fangss None  26643 二月 27 15:40 /bin/x86_64-pc-cygwin-gcc-nm.exe
-rwxr-xr-x 2 fangss None  26643 二月 27 15:40 /bin/x86_64-pc-cygwin-gcc-ranlib.exe
-rwxr-xr-x 2 fangss None 845843 六月 14 2015 /bin/x86_64-w64-mingw32-gcc.exe
-rwxr-xr-x 2 fangss None 845843 六月 14 2015 /bin/x86_64-w64-mingw32-gcc-4.9.2.exe
-rwxr-xr-x 1 fangss None  26131 六月 14 2015 /bin/x86_64-w64-mingw32-gcc-ar.exe
-rwxr-xr-x 1 fangss None  26131 六月 14 2015 /bin/x86_64-w64-mingw32-gcc-nm.exe
-rwxr-xr-x 1 fangss None  26131 六月 14 2015 /bin/x86_64-w64-mingw32-gcc-ranlib.exe

fangss@fangss-PC /cygdrive/c/Users/fangss/workspace/JToy/jni
$ file /bin/*gcc.exe
/bin/gcc.exe:                    PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
/bin/i686-w64-mingw32-gcc.exe:   PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
/bin/x86_64-pc-cygwin-gcc.exe:   PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
/bin/x86_64-w64-mingw32-gcc.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows

fangss@fangss-PC ~
$ ls -ld /lib/gcc/*/*
drwxr-xr-x+ 1 fangss None 0 四月  7 13:56 /lib/gcc/i686-w64-mingw32/4.9.2
drwxr-xr-x+ 1 fangss None 0 四月  1 10:52 /lib/gcc/x86_64-pc-cygwin/5.3.0
drwxr-xr-x+ 1 fangss None 0 四月  7 13:56 /lib/gcc/x86_64-w64-mingw32/4.9.2

$ ls -l /usr
总用量 216
drwxr-xr-x+ 1 fangss None 0 四月  7 15:01 bin
drwxr-xr-x+ 1 fangss None 0 三月 31 11:17 i686-pc-cygwin
drwxr-xr-x+ 1 fangss None 0 四月  7 13:55 i686-w64-mingw32
drwxr-xr-x+ 1 fangss None 0 四月  5 10:00 include
drwxr-xr-x+ 1 fangss None 0 四月  5 10:00 lib
drwxr-xr-x+ 1 fangss None 0 四月  7 13:55 libexec
drwxr-xr-x+ 1 fangss None 0 四月  1 12:19 local
drwxr-xr-x+ 1 fangss None 0 三月 31 11:18 sbin
drwxr-xr-x+ 1 fangss None 0 四月  7 13:55 share
drwxr-xr-x+ 1 fangss None 0 三月 31 11:17 src
drwxr-xr-x+ 1 fangss None 0 三月 31 11:17 ssl
drwxrwxrwt+ 1 fangss None 0 三月 31 11:17 tmp
drwxr-xr-x+ 1 fangss None 0 三月 31 11:17 x86_64-pc-cygwin
drwxr-xr-x+ 1 fangss None 0 四月  7 13:56 x86_64-w64-mingw32
$ gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/5.3.0/lto-wrapper.exe
目标:x86_64-pc-cygwin
配置为:/cygdrive/i/szsz/tmpp/gcc/gcc-5.3.0-3.x86_64/src/gcc-5.3.0/configure --srcdir=/cygdrive/i/szsz/tmpp/gcc/gcc-5.3.0-3.x86_64/src/gcc-5.3.0 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --libexecdir=/usr/lib --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --enable-__cxa_atexit --with-dwarf2 --with-tune=generic --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enable-libcilkrts --enable-libgomp --enable-libitm --enable-libquadmath --enable-libquadmath-support --enable-libssp --enable-libada --enable-libgcj-sublibs --disable-java-awt --disable-symvers --with-ecj-jar=/usr/share/java/ecj.jar --with-gnu-ld --with-gnu-as --with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --enable-linker-build-id --with-default-libstdcxx-abi=gcc4-compatible
线程模型:posix
gcc 版本 5.3.0 (GCC)

$ /bin/x86_64-pc-cygwin-gcc.exe -v  # 同上,因为如下:
$ diff --binary /bin/gcc.exe /bin/x86_64-pc-cygwin-gcc.exe -s
檔案 /bin/gcc.exe 和 /bin/x86_64-pc-cygwin-gcc.exe 相同

其中,文件硬链接相关内容如下 此外,参考How to find and delete all hard links to a file

$ ls -lFhi /bin/gcc # -i选项表示打印节点号inode
89227567617323378 -rwxr-xr-x 3 fangss None 797K 二月 27 15:40 /bin/gcc*

----------------- ----------   ------ ---- ---- ------------  ---------
       |              |           |     |   |       |             |
       |              |           |     |   |       |    File Name(with file classification indicator)
       |              |           |     |   |       |
       |              |           |     |   |       +---  Modification Time
       |              |           |     |   |             
       |              |           |     |   +------------    Size (friendly)
       |              |           |     |                 
       |              |           |     +----------------       Group
       |              |           |                       
       |              |           +----------------------       Owner
       |              |                                   
       |              +----------------------------------  File Permissions
	   |
	   +-------------------------------------------------    Index number


$ stat /bin/gcc.exe
  文件:'/bin/gcc.exe'
  大小:815123          块:800        IO 块:65536  普通文件
设备:8bf74afh/146764975d       Inode:89227567617323378  硬链接:3
权限:(0755/-rwxr-xr-x)  Uid:(197608/  fangss)   Gid:(197121/    None)
最近访问:2016-04-01 10:52:42.933299400 +0800
最近更改:2016-02-27 15:40:54.000000000 +0800
最近改动:2016-04-01 10:52:42.950899500 +0800
创建时间:2016-03-31 11:17:25.731082000 +0800

$ getfacl /bin/gcc.exe
# file: /bin/gcc.exe
# owner: fangss
# group: None
user::rwx
group::r-x
other:r-x

$ find /bin /lib /usr -xdev -samefile /bin/gcc
/bin/gcc.exe
/bin/x86_64-pc-cygwin-gcc-5.3.0.exe
/bin/x86_64-pc-cygwin-gcc.exe
/usr/bin/gcc.exe
/usr/bin/x86_64-pc-cygwin-gcc-5.3.0.exe
/usr/bin/x86_64-pc-cygwin-gcc.exe

$ find /bin /lib /usr -xdev -inum 89227567617323378
/bin/gcc.exe
/bin/x86_64-pc-cygwin-gcc-5.3.0.exe
/bin/x86_64-pc-cygwin-gcc.exe
/usr/bin/gcc.exe
/usr/bin/x86_64-pc-cygwin-gcc-5.3.0.exe
/usr/bin/x86_64-pc-cygwin-gcc.exe

# 其中-xdev选项确保仅在当前文件系统中搜索。
# -xdev  Don't descend directories on other filesystems.

mingw32编译器

$ /bin/i686-w64-mingw32-gcc.exe -v
使用内建 specs。
COLLECT_GCC=/bin/i686-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/bin/../lib/gcc/i686-w64-mingw32/4.9.2/lto-wrapper.exe
目标:i686-w64-mingw32
配置为:/cygdrive/i/szsz/tmpp/cygwin64/mingw64-i686/mingw64-i686-gcc-4.9.2-2.x86_64/src/gcc-4.9.2/configure --srcdir=/cygdrive/i/szsz/tmpp/cygwin64/mingw64-i686/mingw64-i686-gcc-4.9.2-2.x86_64/src/gcc-4.9.2 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/mingw64-i686-gcc --htmldir=/usr/share/doc/mingw64-i686-gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=i686-w64-mingw32 --without-libiconv-prefix --without-libintl-prefix --with-sysroot=/usr/i686-w64-mingw32/sys-root --with-build-sysroot=/usr/i686-w64-mingw32/sys-root --disable-multilib --disable-win32-registry --enable-languages=c,ada,c++,fortran,lto,objc,obj-c++ --enable-fully-dynamic-string --enable-graphite --enable-libgomp --enable-libquadmath --enable-libquadmath-support --enable-libssp --enable-version-specific-runtime-libs --with-dwarf2 --with-gnu-ld --with-gnu-as --with-tune=generic --with-cloog-include=/usr/include/cloog-isl --with-system-zlib --libexecdir=/usr/lib
线程模型:win32
gcc 版本 4.9.2 (GCC)

$ /bin/x86_64-w64-mingw32-gcc.exe -v
使用内建 specs。
COLLECT_GCC=/bin/x86_64-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/bin/../lib/gcc/x86_64-w64-mingw32/4.9.2/lto-wrapper.exe
目标:x86_64-w64-mingw32
配置为:/cygdrive/i/szsz/tmpp/cygwin64/mingw64-x86_64/mingw64-x86_64-gcc-4.9.2-2.x86_64/src/gcc-4.9.2/configure --srcdir=/cygdrive/i/szsz/tmpp/cygwin64/mingw64-x86_64/mingw64-x86_64-gcc-4.9.2-2.x86_64/src/gcc-4.9.2 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/mingw64-x86_64-gcc --htmldir=/usr/share/doc/mingw64-x86_64-gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-w64-mingw32 --without-libiconv-prefix --without-libintl-prefix --with-sysroot=/usr/x86_64-w64-mingw32/sys-root --with-build-sysroot=/usr/x86_64-w64-mingw32/sys-root --disable-multilib --disable-win32-registry --enable-languages=c,ada,c++,fortran,lto,objc,obj-c++ --enable-fully-dynamic-string --enable-graphite --enable-libgomp --enable-libquadmath --enable-libquadmath-support --enable-libssp --enable-version-specific-runtime-libs --with-dwarf2 --with-gnu-ld --with-gnu-as --with-tune=generic --with-cloog-include=/usr/include/cloog-isl --with-system-zlib --libexecdir=/usr/lib
线程模型:win32
gcc 版本 4.9.2 (GCC)

从上面看出

+------------------------+--------------------+------------------+------------------+--------------------+
| PATH(/bin/)            | 目标               | --build          | --host           | --target           |
+------------------------+--------------------+------------------+------------------+--------------------+
|gcc/x86_64-pc-cygwin-gcc| x86_64-pc-cygwin   | x86_64-pc-cygwin | x86_64-pc-cygwin | x86_64-pc-cygwin   |
+------------------------+--------------------+------------------+------------------+--------------------+
| i686-w64-mingw32-gcc   | i686-w64-mingw32   | x86_64-pc-cygwin | x86_64-pc-cygwin | i686-w64-mingw32   |
+------------------------+--------------------+------------------+------------------+--------------------+
| x86_64-w64-mingw32-gcc | x86_64-w64-mingw32 | x86_64-pc-cygwin | x86_64-pc-cygwin | x86_64-w64-mingw32 |
+------------------------+--------------------+------------------+------------------+--------------------+
  • x86_64-pc-cygwin-gcc

默认生成64位的二进制,使用-m32会出错,而-m64可选,因为默认行为。

# 默认
x86_64-pc-cygwin-gcc  -D __int64="long long" -Wl,--add-stdcall-alias -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp

$ file JnToy.dll;nm JnToy.dll | grep JnToy;objdump -p JnToy.dll|grep 'DLL Name'
JnToy.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows
000000046ec91090 T Java_JnToy_parseBytes
        DLL Name: cygwin1.dll
        DLL Name: KERNEL32.dll
 
# 带有-m32,说东西不兼容,它找了64位x86_64-pc-cygwin的路径了
$ x86_64-pc-cygwin-gcc -m32 -D __int64="long long" -Wl,--add-stdcall-alias -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp      
/usr/lib/gcc/x86_64-pc-cygwin/5.3.0/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-cygwin/5.3.0//libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/5.3.0/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/libgcc_s.dll.a when searching for -lgcc_s
  • i686-w64-mingw32-gcc

默认生成32位的二进制,使用-m64会出错,而-m32可选,因为默认行为。

# 默认
$ i686-w64-mingw32-gcc -D __int64="long long" -Wl,--add-stdcall-alias -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp

$ file JnToy.dll;nm JnToy.dll | grep JnToy;objdump -p JnToy.dll|grep 'DLL Name'                                          JnToy.dll: PE32 executable (DLL) (console) Intel 80386, for MS Windows
701814b0 T _Java_JnToy_parseBytes@12
        DLL Name: KERNEL32.dll
        DLL Name: msvcrt.dll

# 带有-m64
$ i686-w64-mingw32-gcc -m64 -D __int64="long long" -Wl,--add-stdcall-alias -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp
JnToy.cpp:1:0: 对不起,尚未实现:未编译入对 64 位模式的支持
  • x86_64-w64-mingw32-gcc

默认生成64位的二进制,使用-m32会出错,而-m64可选,因为默认行为。

# 默认
$ x86_64-w64-mingw32-gcc -D __int64="long long" -Wl,--add-stdcall-alias -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp

$ file JnToy.dll;nm JnToy.dll | grep JnToy;objdump -p JnToy.dll|grep 'DLL Name'
JnToy.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows
000000006ff81430 T Java_JnToy_parseBytes
        DLL Name: KERNEL32.dll
        DLL Name: msvcrt.dll


# 带有-m32
$ x86_64-w64-mingw32-gcc -m32 -D __int64="long long" -Wl,--add-stdcall-alias -I"${JAVA_HOME}\include" -I"${JAVA_HOME}\include\win32" -shared -o JnToy.dll JnToy.cpp
/usr/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libmingw32.a when searching for -lmingw32
/usr/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libmingw32.a when searching for -lmingw32
/usr/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libmingw32.a when searching for -lmingw32
# ...

综上,名字带有x86_64的默认配置并不能产生32位二进制程序,还是暂时需要i686-w64-mingw32-gcc的支持。cygwin的gcc需要cygwin1.dll而mingw需要msvcrt.dll。 对于windows依赖查看可以直接用ldd:

$ ldd JnToy.dll
        ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x77bb0000)
        kernel32.dll => /cygdrive/c/Windows/system32/kernel32.dll (0x77a90000)
        KERNELBASE.dll => /cygdrive/c/Windows/system32/KERNELBASE.dll (0x7fefdc60000)
        ??? => ??? (0x70180000)

$ readelf -d JnToy.dll
readelf:错误:不是 ELF 文件 - 它开头的 magic 字节错误

此外,nm工具貌似不能很好的显示stdcall的符号,对名字重整name mangling处理的不太好,可以使用dependencywalker工具查看,或者dumpbin。 dependencywalker

fangss@fangss-PC /cygdrive/c/Users/fangss/workspace/JToy/jni
$ nm --version
GNU nm (GNU Binutils) 2.25.2
Copyright (C) 2014 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

$ '/cygdrive/d/ProgramFiles/Microsoft Visual Studio 12.0/VC/bin/dumpbin.exe' /EXPORTS JnToy.dll
Microsoft (R) COFF/PE Dumper Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file JnToy.dll

File Type: DLL

  Section contains the following exports for JnToy.dll

    00000000 characteristics
    57072449 time date stamp Fri Apr 08 04:23:53 2016
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 000014B0 Java_JnToy_parseBytes
          2    1 000014B0 Java_JnToy_parseBytes@12

  Summary

        1000 .CRT
        1000 .bss
        1000 .data
        2000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        9000 .debug_info
        2000 .debug_line
        1000 .debug_loc
        1000 .debug_ranges
        1000 .debug_str
        1000 .edata
        1000 .idata
        1000 .rdata
        1000 .reloc
        2000 .text
        1000 .tls
  • 自定义makefile设置

Behavior保持不变,菜单Project里Build Project和Clean...的行为也就和原来一样。

C++ project Settings with a custom makefile using the CDT

# Define a variable for classpath
CLASS_PATH = ../bin
GCC:=i686-w64-mingw32-gcc
OBJ_PATH:=../obj/
LIB_PATH:=../lib/
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

LOCAL_MODULE    := JnToy
LOCAL_JNI_CLASS_FILES := JnToy.class
LOCAL_JNI_H_FILES := JnToy.h
LOCAL_JNI_SRC_FILES := JnToy.cpp



##########################
# +--Project
#    +--bin
#      `--*.class
#    +--src
#      `--*.java
#    +--jni
#      |--*.cpp
#      |--*.h
#      `--Makefile
#    +--obj
#      `--*.o
#    +--lib
#      `--*.dll
#######################
all : $(LOCAL_MODULE).dll	
	$(info [^-^] JAVA_HOME = "$(JAVA_HOME)")
	
# $@ matches the target, $< matches the first dependancy
$(LOCAL_MODULE).dll : $(LOCAL_MODULE).o
	mkdir -p $(LIB_PATH)
	$(GCC) -Wl,--add-stdcall-alias -shared -o $(addprefix $(LIB_PATH),$@) $(addprefix $(OBJ_PATH),$<)

# $@ matches the target, $< matches the first dependancy
$(LOCAL_MODULE).o : $(LOCAL_JNI_SRC_FILES) $(LOCAL_JNI_H_FILES)
	mkdir -p $(OBJ_PATH)
	$(GCC) -I"$(JAVA_HOME)\include" -I"${JAVA_HOME}\include\win32" -c $< -o $(addprefix $(OBJ_PATH),$@)

# $* matches the target filename without the extension
$(LOCAL_JNI_H_FILES) : $(LOCAL_JNI_CLASS_FILES)
	javah -classpath $(CLASS_PATH) $*

.PHONY: clean  ## http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
clean :
	rm $(LOCAL_JNI_H_FILES) $(LOCAL_MODULE).o $(LOCAL_MODULE).dll

Spec, Blog, Guide, FAQ

// #define (\w+) \d+ /\* ([^*]+) \*/ ==> \1\("\2"\),
public enum Errno {
OK("Ok"),
EPERM("Operation not permitted"),
ENOENT("No such file or directory"),
ESRCH("No such process"),
EINTR("Interrupted system call"),
EIO("I/O error"),
ENXIO("No such device or address"),
E2BIG("Argument list too long"),
ENOEXEC("Exec format error"),
EBADF("Bad file number"),
ECHILD("No child processes"),
EAGAIN("Try again"),
ENOMEM("Out of memory"),
EACCES("Permission denied"),
EFAULT("Bad address"),
ENOTBLK("Block device required"),
EBUSY("Device or resource busy"),
EEXIST("File exists"),
EXDEV("Cross-device link"),
ENODEV("No such device"),
ENOTDIR("Not a directory"),
EISDIR("Is a directory"),
EINVAL("Invalid argument"),
ENFILE("File table overflow"),
EMFILE("Too many open files"),
ENOTTY("Not a typewriter"),
ETXTBSY("Text file busy"),
EFBIG("File too large"),
ENOSPC("No space left on device"),
ESPIPE("Illegal seek"),
EROFS("Read-only file system"),
EMLINK("Too many links"),
EPIPE("Broken pipe"),
EDOM("Math argument out of domain of func"),
ERANGE("Math result not representable"),
EDEADLK("Resource deadlock would occur"),
ENAMETOOLONG("File name too long"),
ENOLCK("No record locks available"),
ENOSYS("Function not implemented"),
ENOTEMPTY("Directory not empty"),
ELOOP("Too many symbolic links encountered"),
// #define EWOULDBLOCK EAGAIN /* Operation would block */
E41("Unknown error"),
ENOMSG("No message of desired type"),
EIDRM("Identifier removed"),
ECHRNG("Channel number out of range"),
EL2NSYNC("Level 2 not synchronized"),
EL3HLT("Level 3 halted"),
EL3RST("Level 3 reset"),
ELNRNG("Link number out of range"),
EUNATCH("Protocol driver not attached"),
ENOCSI("No CSI structure available"),
EL2HLT("Level 2 halted"),
EBADE("Invalid exchange"),
EBADR("Invalid request descriptor"),
EXFULL("Exchange full"),
ENOANO("No anode"),
EBADRQC("Invalid request code"),
EBADSLT("Invalid slot"),
// #define EDEADLOCK EDEADLK
E58("Unknown error"),
EBFONT("Bad font file format"),
ENOSTR("Device not a stream"),
ENODATA("No data available"),
ETIME("Timer expired"),
ENOSR("Out of streams resources"),
ENONET("Machine is not on the network"),
ENOPKG("Package not installed"),
EREMOTE("Object is remote"),
ENOLINK("Link has been severed"),
EADV("Advertise error"),
ESRMNT("Srmount error"),
ECOMM("Communication error on send"),
EPROTO("Protocol error"),
EMULTIHOP("Multihop attempted"),
EDOTDOT("RFS specific error"),
EBADMSG("Not a data message"),
EOVERFLOW("Value too large for defined data type"),
ENOTUNIQ("Name not unique on network"),
EBADFD("File descriptor in bad state"),
EREMCHG("Remote address changed"),
ELIBACC("Can not access a needed shared library"),
ELIBBAD("Accessing a corrupted shared library"),
ELIBSCN(".lib section in a.out corrupted"),
ELIBMAX("Attempting to link in too many shared libraries"),
ELIBEXEC("Cannot exec a shared library directly"),
EILSEQ("Illegal byte sequence"),
ERESTART("Interrupted system call should be restarted"),
ESTRPIPE("Streams pipe error"),
EUSERS("Too many users"),
ENOTSOCK("Socket operation on non-socket"),
EDESTADDRREQ("Destination address required"),
EMSGSIZE("Message too long"),
EPROTOTYPE("Protocol wrong type for socket"),
ENOPROTOOPT("Protocol not available"),
EPROTONOSUPPORT("Protocol not supported"),
ESOCKTNOSUPPORT("Socket type not supported"),
EOPNOTSUPP("Operation not supported on transport endpoint"),
EPFNOSUPPORT("Protocol family not supported"),
EAFNOSUPPORT("Address family not supported by protocol"),
EADDRINUSE("Address already in use"),
EADDRNOTAVAIL("Cannot assign requested address"),
ENETDOWN("Network is down"),
ENETUNREACH("Network is unreachable"),
ENETRESET("Network dropped connection because of reset"),
ECONNABORTED("Software caused connection abort"),
ECONNRESET("Connection reset by peer"),
ENOBUFS("No buffer space available"),
EISCONN("Transport endpoint is already connected"),
ENOTCONN("Transport endpoint is not connected"),
ESHUTDOWN("Cannot send after transport endpoint shutdown"),
ETOOMANYREFS("Too many references: cannot splice"),
ETIMEDOUT("Connection timed out"),
ECONNREFUSED("Connection refused"),
EHOSTDOWN("Host is down"),
EHOSTUNREACH("No route to host"),
EALREADY("Operation already in progress"),
EINPROGRESS("Operation now in progress"),
ESTALE("Stale NFS file handle"),
EUCLEAN("Structure needs cleaning"),
ENOTNAM("Not a XENIX named type file"),
ENAVAIL("No XENIX semaphores available"),
EISNAM("Is a named type file"),
ENOKEY("Required key not available"),
EKEYEXPIRED("Key has expired"),
EKEYREVOKED("Key has been revoked"),
EKEYREJECTED("Key was rejected by service"),
EOWNERDEAD("Owner died"),
ENOTRECOVERABLE("State not recoverable"),
ERFKILL("Operation not possible due to RF-kill"),
EHWPOISON("Memory page has hardware error");
private Errno(String msg) {
this.msg = msg;
}
private final String msg;
public String getMsg() {
return msg;
}
}
  • 通过JDK提供的工具jps列出所有Java进程,找到目标进程PID;
  • 通过gdb附加到目标进程,此时需要符号和源文件,以方便调试,另外编译器最好有调试选项如-g(i686-w64-mingw32-g++ -g -Wl,--add-stdcall-alias ...)

gdb

在GDB启动时,除了选项之外,它把所有的参数都看作是可执行文件和core文件(或者是进程ID)来读取。就如同这些参数已分别被“-se”和“-c”(或者是“-p”)选项所修饰过一样。(GDB读取的第一个参数,如果没有关联的选项标志,就等同于“-se”选项后面参数;如果有第二个这样的参数的话,就等同于“-c”/“-p”选项后的参数)如果第二个参数是以一个10进制数开头的话,GDB首先会尝试把它作为一个进程去附着,如果失败了的话,就尝试着把它作为core文件打开。如果有一个文件名以数字开头的core文件的话,可用通过附加./前缀来避免GDB把它当成pid,如./12345。如果GDB已经被配置为不支持core文件,比如大部分的嵌入式目标,它将拒绝第二个参数而忽略它。

如c:/MinGW/bin/gdb -directory=C:\Users\fangss\workspace\JToy\jni C:\Users\fangss\works pace\JToy\lib\JnToy.dll 9056,其中没有“-”的选项被当做符号文件和PID

C:\Users\fangss>jps
8032 Jps
9056 JnToy
3928

C:\Users\fangss>c:/MinGW/bin/gdb -directory=C:\Users\fangss\workspace\JToy\jni C:\Users\fangss\works
pace\JToy\lib\JnToy.dll 9056
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\fangss\workspace\JToy\lib\JnToy.dll...done.
Attaching to program `C:\Users\fangss\workspace\JToy\lib\JnToy.dll', process 9056
[New Thread 9056.0x1a24]
[New Thread 9056.0x2278]
[New Thread 9056.0x233c]
[New Thread 9056.0x22e0]
[New Thread 9056.0x2378]
[New Thread 9056.0x1b9c]
[New Thread 9056.0x1ac8]
[New Thread 9056.0x2228]
[New Thread 9056.0x1adc]
[New Thread 9056.0x21ac]
[New Thread 9056.0x1984]
[New Thread 9056.0x18e0]
[New Thread 9056.0x2148]
[New Thread 9056.0x2308]
[New Thread 9056.0x111c]
(gdb) info sources
Source files for which symbols have been read in:



Source files for which symbols will be read in on demand:

/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/dllmain.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/dllentry.c,
/usr/src/debug/mingw64-i686-gcc-4.9.2-2/libgcc/libgcc2.c,
/usr/src/debug/mingw64-i686-gcc-4.9.2-2/libgcc/config/i386/cygwin.S,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/CRT_fp10.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/pesect.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/pseudo-reloc-list.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/tlsmcrt.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/tlsthrd.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/pseudo-reloc.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/mingw_helpers.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/cinitexe.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/tlssup.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/gs_support.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/natstart.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/gccmain.c,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/atonexit.c,
C:\Users\fangss\workspace\JToy\jni\jni.h, C:\Users\fangss\workspace\JToy\jni\ScopedUtfChars.h,
D:\ProgramFiles\Java\jdk1.8.0_40\include\jni.h, C:\Users\fangss\workspace\JToy\jni\JnToy.cpp,
/usr/i686-w64-mingw32/sys-root/mingw/include/psdk_inc/intrin-impl.h,
/usr/src/debug/mingw64-i686-runtime-4.0.6-1/crt/crtdll.c
(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
0x779e0000  0x77b44d2c  Yes (*)     C:\Windows\SysWOW64\ntdll.dll
0x75ad0000  0x75bcada8  Yes (*)     C:\Windows\syswow64\kernel32.dll
0x76b71000  0x76bb6a18  Yes (*)     C:\Windows\syswow64\KernelBase.dll
0x76ad1000  0x76b6f050  Yes (*)     C:\Windows\syswow64\advapi32.dll
0x75451000  0x754fb2c4  Yes (*)     C:\Windows\syswow64\msvcrt.dll
0x76bc1000  0x76bd8ed8  Yes (*)     C:\Windows\SysWOW64\sechost.dll
0x76d10000  0x76de4e00  Yes (*)     C:\Windows\syswow64\rpcrt4.dll
0x75400000  0x754411f0  Yes (*)     C:\Windows\syswow64\sspicli.dll
0x753e1000  0x753eb474  Yes (*)     C:\Windows\syswow64\cryptbase.dll
0x75be0000  0x75cc3198  Yes (*)     C:\Windows\syswow64\user32.dll
0x77350000  0x773c1930  Yes (*)     C:\Windows\syswow64\gdi32.dll
0x772a1000  0x772a92f8  Yes (*)     C:\Windows\syswow64\lpk.dll
0x76a31000  0x76acc9fc  Yes (*)     C:\Windows\syswow64\usp10.dll
0x70af1000  0x70c8d18c  Yes (*)     C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b641
44ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
0x76df1000  0x76e46b60  Yes (*)     C:\Windows\syswow64\shlwapi.dll
0x75ce0000  0x75d20ce0  Yes (*)     C:\Windows\system32\imm32.dll
0x75581000  0x7564bee0  Yes (*)     C:\Windows\syswow64\msctf.dll
0x66b21000  0x66bdec24  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\msvcr100.dll
0x52161000  0x5250300e  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\client\jvm.dll
0x707f1000  0x707f6108  Yes (*)     C:\Windows\system32\wsock32.dll
0x76f71000  0x76fa4784  Yes (*)     C:\Windows\syswow64\ws2_32.dll
0x772b1000  0x772b5058  Yes (*)     C:\Windows\syswow64\nsi.dll
0x71901000  0x71931264  Yes (*)     C:\Windows\system32\winmm.dll
0x779a1000  0x779a4050  Yes (*)     C:\Windows\syswow64\psapi.dll
0x66c91000  0x66c9b71c  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\verify.dll
0x66c61000  0x66c80508  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\java.dll
0x66c31000  0x66c58b0c  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\jdwp.dll
0x66c21000  0x66c26202  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\npt.dll
0x66c01000  0x66c12600  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\zip.dll
0x75de1000  0x76a2a8ac  Yes (*)     C:\Windows\syswow64\shell32.dll
0x77471000  0x775cb0cc  Yes (*)     C:\Windows\syswow64\ole32.dll
0x75dc1000  0x75dca440  Yes (*)     C:\Windows\syswow64\profapi.dll
0x66bf1000  0x66bf738e  Yes (*)     C:\Program Files (x86)\Java\jdk1.8.0_25\jre\bin\dt_socket.dll
0x70f11000  0x70f1f830  Yes (*)     C:\Windows\system32\nlaapi.dll
0x70f01000  0x70f0f90c  Yes (*)     C:\Windows\system32\NapiNSP.dll
0x70ee1000  0x70ef1e28  Yes (*)     C:\Windows\system32\pnrpnsp.dll
0x72991000  0x729cb8d8  Yes (*)     C:\Windows\System32\mswsock.dll
0x721b1000  0x721f36a0  Yes (*)     C:\Windows\system32\dnsapi.dll
0x70ed1000  0x70ed733c  Yes (*)     C:\Windows\System32\winrnr.dll
0x729f1000  0x72a0b944  Yes (*)     C:\Windows\system32\IPHLPAPI.DLL
0x729e1000  0x729e621c  Yes (*)     C:\Windows\system32\winnsi.dll
0x70e71000  0x70ea774c  Yes (*)     C:\Windows\System32\FWPUCLNT.DLL
0x70eb1000  0x70eb515c  Yes (*)     C:\Windows\system32\rasadhlp.dll
0x046b1000  0x046e9164  Yes (*)     C:\Program Files (x86)\Tencent\QQWifi\GameAcc\QQVIPLSP_51.dll
0x75311000  0x7531831c  Yes (*)     C:\Windows\system32\version.dll
0x727c1000  0x7284614e  Yes (*)     C:\Windows\WinSxS\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50
727.6229_none_d089f796442de10e\msvcp80.dll
0x72851000  0x728ea7e6  Yes (*)     C:\Windows\WinSxS\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50
727.6229_none_d089f796442de10e\msvcr80.dll
0x72631000  0x7263406c  Yes (*)     C:\Windows\System32\WSHTCPIP.DLL
0x6cdc1000  0x6cdcb270  Yes         C:\Users\fangss\workspace\JToy\lib\JnToy.dll
0x6cec1000  0x6cee3020  Yes (*)     D:\ProgramFiles\GtkSharp\2.12\bin\libgcc_s_sjlj-1.dll
0x6fc41000  0x6fd1801c  Yes (*)     D:\ProgramFiles\GtkSharp\2.12\bin\libstdc++-6.dll
(*): Shared library is missing debugging information.
(gdb) x/20i Java_JnToy_NewObject
No symbol "Java_JnToy_NewObject" in current context.
(gdb) break JnToy.cpp:351   # break <source file name>:<line number>
Breakpoint 1 at 0x6cdc1bc9: file JnToy.cpp, line 351.
(gdb) c
Continuing.
[New Thread 9056.0x1f44]
[New Thread 9056.0x1534]
[Switching to Thread 9056.0x2278]

Breakpoint 1, Java_JnToy_NewObject@24 (env=0x25ec938, UNUSED_thiz=0x264fa9c, clazz=0x264fab0,
    mid=349193040, params=0x264faa4) at JnToy.cpp:354
354       jvalue *args = NULL;
(gdb)
/**
JNIEnv *e;
jobject method;
// e->FromReflectedMethod(e, mid); // in c
// e->FromReflectedMethod(mid); // in c++
// I think it's a nice idea to define INLINE functions with a prefix jni to make
// it unified and simple for c or c++ except all interfaces needing definition.
//jniFromReflectedMethod(e, mid);
// JavaScript
1. /^[\t ]*(([\w_*]+[\t ]+)+)(\*?)[\t ]*(\w+)\(([^)]*)\)\s*{/gm ==> INLINE \1\3jni\4\(JNIEnv *env, \5\){
2. functions ==> env
3. to c: /this[\t ]*(,?)/g ==> env\1 to c++ /this[\t ]*(,?)/g ==>
replace "env->([^(]+)\(" ----with----> "JNI_CALL\(\1, env,"
e.g.
#include "jni.h"
extern "C" {
// native static long FromReflectedConstructor(Constructor<?> ctor);
JNIEXPORT jlong JNICALL Java_JnToy_FromReflectedConstructor(JNIEnv *env, jclass UNUSED(cls), jobject method) {
// cast jmethodID to jlong
return REINTERPRET_CAST(jlong, jniFromReflectedMethod(env, method));
}
// native static long FromReflectedMethod(Method method);
JNIEXPORT jlong JNICALL Java_JnToy_FromReflectedMethod(JNIEnv *env, jclass UNUSED(cls), jobject method) {
// cast jmethodID to jlong
return REINTERPRET_CAST(jlong, jniFromReflectedMethod(env, method));
}
}
*/
#ifndef _Included_JNI
#define _Included_JNI
//////////////////////////////////////////////////////////////////
// instead of include/win32/jni_md.h when you use cygwin on windows.
/* jni_md.h contains the machine-dependent typedefs for jbyte, jint and jlong */
//==================jni_md.h=================//
// #ifndef _JAVASOFT_JNI_MD_H_ //
// #define _JAVASOFT_JNI_MD_H_ //
// //
// #define JNIEXPORT __declspec(dllexport) //
// #define JNIIMPORT __declspec(dllimport) //
// #define JNICALL __stdcall //
// //
// typedef long jint; //
// typedef __int64 jlong; //
// typedef signed char jbyte; //
// //
// #endif /* !_JAVASOFT_JNI_MD_H_ */ //
//===========================================//
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
#include <stdint.h>
typedef int32_t jint; /* signed 32 bits */
#ifdef __GNUC__
typedef long long jlong;
#else
typedef __int64 jlong;
#endif
typedef signed char jbyte;
///* [JNI Types and Data Structures](http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp9502) */
///* https://android.googlesource.com/platform/libnativehelper/+/master/include/nativehelper/jni.h */
//
// #include <stdint.h>
///* Primitive types that match up with Java equivalents. */
//typedef uint8_t jboolean; /* unsigned 8 bits */
//typedef int8_t jbyte ; /* signed 8 bits */
//typedef uint16_t jchar ; /* unsigned 16 bits */
//typedef int16_t jshort ; /* signed 16 bits */
//typedef int32_t jint ; /* signed 32 bits */
//typedef int64_t jlong ; /* signed 64 bits */
//typedef float jfloat ; /* 32-bit IEEE 754 */
//typedef double jdouble ; /* 64-bit IEEE 754 */
#endif /* !_JAVASOFT_JNI_MD_H_ */
/////////////////////////////////////////////////////////////////////
#include <jni.h>
//#include <stdarg.h>
// Explicitly assert the consistency and correctness of mapping Java Primitive types to native C types.
union __verify_primitive_types_against_java_peer_types
{
char int8_t_eq_jboolean[1 == sizeof(jboolean) ? 1 : -1];
char int8_t_eq_jbyte [1 == sizeof(jbyte ) ? 1 : -1];
char int16_t_eq_jchar [2 == sizeof(jchar ) ? 1 : -1];
char int16_t_eq_jshort [2 == sizeof(jshort ) ? 1 : -1];
char int32_t_eq_jint [4 == sizeof(jint ) ? 1 : -1];
char int64_t_eq_jlong [8 == sizeof(jlong ) ? 1 : -1];
char float_eq_jfloat [4 == sizeof(jfloat ) ? 1 : -1];
char double_eq_jdouble [8 == sizeof(jdouble ) ? 1 : -1];
};
/*
e.g.
JNIEXPORT void JNICALL Java_test_n(JNIEnv *env, jobject obj, jobject o)
{
jmethodID jmid = JNI_ENV_PTR(env) -> FromReflectedMethod(JNI_ENV_ARG(env, o));
JNI_ENV_PTR(env) -> CallVoidMethod(JNI_ENV_ARG(env, obj), jmid, 7);
return;
}
*/
#ifdef __cplusplus
# define JNI_ENV_ARG(x, y) y
# define JNI_ENV_PTR(x) x
# define JNI_CALL(FUNC, ENV, ...) ENV->FUNC(__VA_ARGS__)
#else
# define JNI_ENV_ARG(x,y) x, y
# define JNI_ENV_PTR(x) (*x)
# define JNI_CALL(FUNC, ENV, ...) (*ENV)->FUNC(ENV, ##__VA_ARGS__)
#endif
#ifndef INLINE
/* Don't vs2013 12.0.21005.1 REL c compiler support c99 inline? */
#if defined _MSC_VER && !defined __cplusplus
# define INLINE __inline
#else
# define INLINE inline
#endif
#endif
typedef jboolean JBoolean;
typedef jbyte JByte;
typedef jchar JChar;
typedef jshort JShort;
typedef jint JInt;
typedef jlong JLong;
typedef jfloat JFloat;
typedef jdouble JDouble;
/**
* Version Information
*
* Returns the version of the native method interface.
*
*
* LINKAGE:
* Index 4 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
*
* RETURNS:
* Returns the major version number in the higher 16 bits and the minor version number in the lower 16 bits.
*
* In JDK/JRE 1.1, GetVersion() returns 0x00010001.
* In JDK/JRE 1.2, GetVersion() returns 0x00010002.
* In JDK/JRE 1.4, GetVersion() returns 0x00010004.
* In JDK/JRE 1.6, GetVersion() returns 0x00010006.
*/
INLINE jint jniGetVersion(JNIEnv *env) {
return JNI_CALL(GetVersion, env);
}
INLINE jclass jniDefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len) {
return JNI_CALL(DefineClass, env, name, loader, buf, len);
}
/**
* jclass FindClass(JNIEnv *env, const char *name);
*
* In JDK release 1.1, this function loads a locally-defined class. It searches the directories and zip files specified by the CLASSPATH environment variable for the
* class with the specified name.
*
* Since Java 2 SDK release 1.2, the Java security model allows non-system classes to load and call native methods. FindClass locates the class loader associated with
* the current native method; that is, the class loader of the class that declared the native method. If the native method belongs to a system class, no class loader
* will be involved. Otherwise, the proper class loader will be invoked to load and link the named class.
*
* Since Java 2 SDK release 1.2, when FindClass is called through the Invocation Interface, there is no current native method or its associated class loader. In that
* case, the result of ClassLoader.getSystemClassLoader is used. This is the class loader the virtual machine creates for applications, and is able to locate classes
* listed in the java.class.path property.
*
* The name argument is a fully-qualified class name or an array type signature . For example, the fully-qualified class name for the java.lang.String class is:
*
* "java/lang/String"
*
* The array type signature of the array class java.lang.Object[] is:
*
* "[Ljava/lang/Object;"
*
*
* LINKAGE:
* Index 6 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* name: a fully-qualified class name (that is, a package name, delimited by “/”, followed by the class name).
* If the name begins with “[“ (the array signature character), it returns an array class. The string is encoded in modified UTF-8.
*
* RETURNS:
* Returns a class object from a fully-qualified name, or NULL if the class cannot be found.
*
* THROWS:
* ClassFormatError: if the class data does not specify a valid class.
* ClassCircularityError: if a class or interface would be its own superclass or superinterface.
* NoClassDefFoundError: if no definition for a requested class or interface can be found.
* OutOfMemoryError: if the system runs out of memory.
*/
INLINE jclass jniFindClass(JNIEnv *env, const char *name) {
return JNI_CALL(FindClass, env, name);
}
/**
* jmethodID FromReflectedMethod(JNIEnv *env, jobject method);
*
* Converts a `java.lang.reflect.Method` or `java.lang.reflect.Constructor` object to a method ID.
*
* LINKAGE: Index 7 in the JNIEnv interface function table.
*
* SINCE: JDK/JRE 1.2
*/
INLINE jmethodID jniFromReflectedMethod(JNIEnv *env, jobject method) {
return JNI_CALL(FromReflectedMethod, env, method);
}
/**
* jfieldID FromReflectedField(JNIEnv *env, jobject field);
*
* Converts a `java.lang.reflect.Field` to a field ID.
*
* LINKAGE: Index 8 in the JNIEnv interface function table.
*
* SINCE: JDK/JRE 1.2
*/
INLINE jfieldID jniFromReflectedField(JNIEnv *env, jobject field) {
return JNI_CALL(FromReflectedField, env, field);
}
/**
* jobject ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
*
* Converts a method ID derived from `cls` to a `java.lang.reflect.Method` or `java.lang.reflect.Constructor` object.
* `isStatic` must be set to `JNI_TRUE` if the method ID refers to a static field, and `JNI_FALSE` otherwise.
*
* Throws OutOfMemoryError and returns 0 if fails.
*
* LINKAGE: Index 9 in the JNIEnv interface function table.
*
* SINCE: JDK/JRE 1.2
*/
INLINE jobject jniToReflectedMethod(JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic) {
return JNI_CALL(ToReflectedMethod, env, cls, methodID, isStatic);
}
/**
* jclass GetSuperclass(JNIEnv *env, jclass clazz);
*
* If clazz represents any class other than the class Object, then this function returns the object that represents the superclass of the class specified by clazz.
* If clazz specifies the class Object, or clazz represents an interface, this function returns NULL.
*
*
* LINKAGE: Index 10 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz: a Java class object.
*
* RETURNS:
* Returns the superclass of the class represented by clazz, or NULL.
*/
INLINE jclass jniGetSuperclass(JNIEnv *env, jclass sub) {
return JNI_CALL(GetSuperclass, env, sub);
}
/**
* jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1, jclass clazz2);
*
* Determines whether an object of clazz1 can be safely cast to clazz2.
*
* LINKAGE: Index 11 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz1: the first class argument.
* clazz2: the second class argument.
*
* RETURNS:
* Returns JNI_TRUE if either of the following is true:
* The first and second class arguments refer to the same Java class.
* The first class is a subclass of the second class.
* The first class has the second class as one of its interfaces.
*/
INLINE jboolean jniIsAssignableFrom(JNIEnv *env, jclass sub, jclass sup) {
return JNI_CALL(IsAssignableFrom, env, sub, sup);
}
/**
* jobject ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
*
* Converts a field ID derived from `cls` to a `java.lang.reflect.Field` object. `isStatic` must be set to `JNI_TRUE` if `fieldID` refers to a static field, and `JNI_FALSE` otherwise.
*
* Throws OutOfMemoryError and returns 0 if fails.
*
* LINKAGE: Index 12 in the JNIEnv interface function table.
*
* SINCE:
* JDK/JRE 1.2
*/
INLINE jobject jniToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic) {
return JNI_CALL(ToReflectedField, env, cls, fieldID, isStatic);
}
INLINE jint jniThrow(JNIEnv *env, jthrowable obj) {
return JNI_CALL(Throw, env, obj);
}
INLINE jint jniThrowNew(JNIEnv *env, jclass clazz, const char *msg) {
return JNI_CALL(ThrowNew, env, clazz, msg);
}
INLINE jthrowable jniExceptionOccurred(JNIEnv *env) {
return JNI_CALL(ExceptionOccurred, env);
}
/**
* void ExceptionDescribe(JNIEnv *env);
*
* Prints an exception and a backtrace of the stack to a system error-reporting
* channel, such as stderr. This is a convenience routine provided for debugging.
*
* LINKAGE: Index 16 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
*/
INLINE void jniExceptionDescribe(JNIEnv *env) {
JNI_CALL(ExceptionDescribe, env);
}
/**
* void ExceptionClear(JNIEnv *env);
*
* Clears any exception that is currently being thrown. If no exception is
* currently being thrown, this routine has no effect.
*
* LINKAGE: Index 17 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
*/
INLINE void jniExceptionClear(JNIEnv *env) {
JNI_CALL(ExceptionClear, env);
}
/**
* void FatalError(JNIEnv *env, const char *msg);
*
* Raises a fatal error and does not expect the VM to recover. This function does not return.
*
* LINKAGE: Index 18 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
*
* msg: an error message. The string is encoded in modified UTF-8.
*/
INLINE void jniFatalError(JNIEnv *env, const char *msg) {
JNI_CALL(FatalError, env, msg);
}
INLINE jint jniPushLocalFrame(JNIEnv *env, jint capacity) {
return JNI_CALL(PushLocalFrame, env, capacity);
}
INLINE jobject jniPopLocalFrame(JNIEnv *env, jobject result) {
return JNI_CALL(PopLocalFrame, env, result);
}
INLINE jobject jniNewGlobalRef(JNIEnv *env, jobject lobj) {
return JNI_CALL(NewGlobalRef, env, lobj);
}
INLINE void jniDeleteGlobalRef(JNIEnv *env, jobject gref) {
JNI_CALL(DeleteGlobalRef, env, gref);
}
INLINE void jniDeleteLocalRef(JNIEnv *env, jobject obj) {
JNI_CALL(DeleteLocalRef, env, obj);
}
INLINE jboolean jniIsSameObject(JNIEnv *env, jobject obj1, jobject obj2) {
return JNI_CALL(IsSameObject, env, obj1, obj2);
}
INLINE jobject jniNewLocalRef(JNIEnv *env, jobject ref) {
return JNI_CALL(NewLocalRef, env, ref);
}
INLINE jint jniEnsureLocalCapacity(JNIEnv *env, jint capacity) {
return JNI_CALL(EnsureLocalCapacity, env, capacity);
}
//
/// Object Operations
//
/**
* AllocObject
* jobject AllocObject(JNIEnv *env, jclass clazz);
*
* Allocates a new Java object without invoking any of the constructors for the object. Returns a reference to the object.
*
* The clazz argument must not refer to an array class.
*
*
* LINKAGE:
* Index 27 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz: a Java class object.
*
* RETURNS:
* Returns a Java object, or NULL if the object cannot be constructed.
*
* THROWS:
* InstantiationException: if the class is an interface or an abstract class.
*
* OutOfMemoryError: if the system runs out of memory.
*/
INLINE jobject jniAllocObject(JNIEnv *env, jclass clazz) {
return JNI_CALL(AllocObject, env, clazz);
}
/**
* jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
* jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
* jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
*
* Constructs a new Java object. The method ID indicates which constructor method to invoke. This ID must be obtained by calling GetMethodID() with <init> as the method name and void (V) as the return type.
*
* The clazz argument must not refer to an array class.
*
* NewObject
* Programmers place all arguments that are to be passed to the constructor immediately following the methodID argument. NewObject() accepts these arguments and passes them to the Java method that the programmer wishes to invoke.
*
* LINKAGE:
* Index 28 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz: a Java class object.
* methodID: the method ID of the constructor.
* ...: arguments to the constructor.
*
* RETURNS:
* Returns a Java object, or NULL if the object cannot be constructed.
*
* THROWS:
* InstantiationException: if the class is an interface or an abstract class.
* OutOfMemoryError: if the system runs out of memory.
* Any exceptions thrown by the constructor.
*/
INLINE jobject jniNewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jobject result;
va_start(args, methodID);
result = JNI_CALL(NewObjectV, env, clazz, methodID, args);
va_end(args);
return result;
}
/**
* @see jniNewObject
*
* NewObjectV
* Programmers place all arguments that are to be passed to the constructor in an args argument of type va_list that immediately follows the methodID argument. NewObjectV() accepts these arguments, and, in turn, passes them to the Java method that the programmer wishes to invoke.
*
* LINKAGE:
* Index 29 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz: a Java class object.
* methodID: the method ID of the constructor.
* args: a va_list of arguments to the constructor.
*
* RETURNS:
* Returns a Java object, or NULL if the object cannot be constructed.
*
* THROWS:
* InstantiationException: if the class is an interface or an abstract class.
* OutOfMemoryError: if the system runs out of memory.
* Any exceptions thrown by the constructor.
*/
INLINE jobject jniNewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(NewObjectV, env, clazz, methodID, args);
}
/**
* @see jniNewObject
*
* NewObjectA
* Programmers place all arguments that are to be passed to the constructor in an args array of jvalues that immediately follows the methodID argument. NewObjectA() accepts the arguments in this array, and, in turn, passes them to the Java method that the programmer wishes to invoke.
*
* LINKAGE:
* Index 30 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz: a Java class object.
* methodID: the method ID of the constructor.
* args: an array of arguments to the constructor.
*
* RETURNS:
* Returns a Java object, or NULL if the object cannot be constructed.
*
* THROWS:
* InstantiationException: if the class is an interface or an abstract class.
* OutOfMemoryError: if the system runs out of memory.
* Any exceptions thrown by the constructor.
*/
INLINE jobject jniNewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(NewObjectA, env, clazz, methodID, args);
}
INLINE jclass jniGetObjectClass(JNIEnv *env, jobject obj) {
return JNI_CALL(GetObjectClass, env, obj);
}
INLINE jboolean jniIsInstanceOf(JNIEnv *env, jobject obj, jclass clazz) {
return JNI_CALL(IsInstanceOf, env, obj, clazz);
}
/**
* jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
*
* Returns the method ID for an instance (nonstatic) method of a class or interface. The method may be defined in one of the clazz’s superclasses and inherited by clazz. The method is determined by its name and signature.
*
* GetMethodID() causes an uninitialized class to be initialized.
*
* To obtain the method ID of a constructor, supply <init> as the method name and void (V) as the return type.
*
* LINKAGE:
* Index 33 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* clazz: a Java class object.
* name: the method name in a 0-terminated modified UTF-8 string.
* sig: the method signature in 0-terminated modified UTF-8 string.
*
* RETURNS:
* Returns a method ID, or NULL if the specified method cannot be found.
*
* THROWS:
* NoSuchMethodError: if the specified method cannot be found.
* ExceptionInInitializerError: if the class initializer fails due to an exception.
* OutOfMemoryError: if the system runs out of memory.
*/
INLINE jmethodID jniGetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
return JNI_CALL(GetMethodID, env, clazz, name, sig);
}
INLINE jobject jniCallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jobject result;
va_start(args, methodID);
result = JNI_CALL(CallObjectMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jobject jniCallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallObjectMethodV, env, obj, methodID, args);
}
INLINE jobject jniCallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallObjectMethodA, env, obj, methodID, args);
}
INLINE jboolean jniCallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jboolean result;
va_start(args, methodID);
result = JNI_CALL(CallBooleanMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jboolean jniCallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallBooleanMethodV, env, obj, methodID, args);
}
INLINE jboolean jniCallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallBooleanMethodA, env, obj, methodID, args);
}
INLINE jbyte jniCallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jbyte result;
va_start(args, methodID);
result = JNI_CALL(CallByteMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jbyte jniCallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallByteMethodV, env, obj, methodID, args);
}
INLINE jbyte jniCallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallByteMethodA, env, obj, methodID, args);
}
INLINE jchar jniCallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jchar result;
va_start(args, methodID);
result = JNI_CALL(CallCharMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jchar jniCallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallCharMethodV, env, obj, methodID, args);
}
INLINE jchar jniCallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallCharMethodA, env, obj, methodID, args);
}
INLINE jshort jniCallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jshort result;
va_start(args, methodID);
result = JNI_CALL(CallShortMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jshort jniCallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallShortMethodV, env, obj, methodID, args);
}
INLINE jshort jniCallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallShortMethodA, env, obj, methodID, args);
}
INLINE jint jniCallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jint result;
va_start(args, methodID);
result = JNI_CALL(CallIntMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jint jniCallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallIntMethodV, env, obj, methodID, args);
}
INLINE jint jniCallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallIntMethodA, env, obj, methodID, args);
}
INLINE jlong jniCallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jlong result;
va_start(args, methodID);
result = JNI_CALL(CallLongMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jlong jniCallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallLongMethodV, env, obj, methodID, args);
}
INLINE jlong jniCallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallLongMethodA, env, obj, methodID, args);
}
INLINE jfloat jniCallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jfloat result;
va_start(args, methodID);
result = JNI_CALL(CallFloatMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jfloat jniCallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallFloatMethodV, env, obj, methodID, args);
}
INLINE jfloat jniCallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallFloatMethodA, env, obj, methodID, args);
}
INLINE jdouble jniCallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
jdouble result;
va_start(args, methodID);
result = JNI_CALL(CallDoubleMethodV, env, obj, methodID, args);
va_end(args);
return result;
}
INLINE jdouble jniCallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
return JNI_CALL(CallDoubleMethodV, env, obj, methodID, args);
}
INLINE jdouble jniCallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallDoubleMethodA, env, obj, methodID, args);
}
INLINE void jniCallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
va_list args;
va_start(args, methodID);
JNI_CALL(CallVoidMethodV, env, obj, methodID, args);
va_end(args);
}
INLINE void jniCallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) {
JNI_CALL(CallVoidMethodV, env, obj, methodID, args);
}
INLINE void jniCallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args) {
JNI_CALL(CallVoidMethodA, env, obj, methodID, args);
}
INLINE jobject jniCallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jobject result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualObjectMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jobject jniCallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualObjectMethodV, env, obj, clazz, methodID, args);
}
INLINE jobject jniCallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualObjectMethodA, env, obj, clazz, methodID, args);
}
INLINE jboolean jniCallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jboolean result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualBooleanMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jboolean jniCallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualBooleanMethodV, env, obj, clazz, methodID, args);
}
INLINE jboolean jniCallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
const jvalue * args) {
return JNI_CALL(CallNonvirtualBooleanMethodA, env, obj, clazz, methodID, args);
}
INLINE jbyte jniCallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jbyte result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualByteMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jbyte jniCallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualByteMethodV, env, obj, clazz, methodID, args);
}
INLINE jbyte jniCallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualByteMethodA, env, obj, clazz, methodID, args);
}
INLINE jchar jniCallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jchar result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualCharMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jchar jniCallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualCharMethodV, env, obj, clazz, methodID, args);
}
INLINE jchar jniCallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualCharMethodA, env, obj, clazz, methodID, args);
}
INLINE jshort jniCallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jshort result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualShortMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jshort jniCallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualShortMethodV, env, obj, clazz, methodID, args);
}
INLINE jshort jniCallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualShortMethodA, env, obj, clazz, methodID, args);
}
INLINE jint jniCallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jint result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualIntMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jint jniCallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualIntMethodV, env, obj, clazz, methodID, args);
}
INLINE jint jniCallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualIntMethodA, env, obj, clazz, methodID, args);
}
INLINE jlong jniCallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jlong result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualLongMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jlong jniCallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualLongMethodV, env, obj, clazz, methodID, args);
}
INLINE jlong jniCallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualLongMethodA, env, obj, clazz, methodID, args);
}
INLINE jfloat jniCallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jfloat result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualFloatMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jfloat jniCallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualFloatMethodV, env, obj, clazz, methodID, args);
}
INLINE jfloat jniCallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualFloatMethodA, env, obj, clazz, methodID, args);
}
INLINE jdouble jniCallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
jdouble result;
va_start(args, methodID);
result = JNI_CALL(CallNonvirtualDoubleMethodV, env, obj, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jdouble jniCallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallNonvirtualDoubleMethodV, env, obj, clazz, methodID, args);
}
INLINE jdouble jniCallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
return JNI_CALL(CallNonvirtualDoubleMethodA, env, obj, clazz, methodID, args);
}
INLINE void jniCallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) {
va_list args;
va_start(args, methodID);
JNI_CALL(CallNonvirtualVoidMethodV, env, obj, clazz, methodID, args);
va_end(args);
}
INLINE void jniCallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) {
JNI_CALL(CallNonvirtualVoidMethodV, env, obj, clazz, methodID, args);
}
INLINE void jniCallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args) {
JNI_CALL(CallNonvirtualVoidMethodA, env, obj, clazz, methodID, args);
}
INLINE jfieldID jniGetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
return JNI_CALL(GetFieldID, env, clazz, name, sig);
}
INLINE jobject jniGetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetObjectField, env, obj, fieldID);
}
INLINE jboolean jniGetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetBooleanField, env, obj, fieldID);
}
INLINE jbyte jniGetByteField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetByteField, env, obj, fieldID);
}
INLINE jchar jniGetCharField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetCharField, env, obj, fieldID);
}
INLINE jshort jniGetShortField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetShortField, env, obj, fieldID);
}
INLINE jint jniGetIntField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetIntField, env, obj, fieldID);
}
INLINE jlong jniGetLongField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetLongField, env, obj, fieldID);
}
INLINE jfloat jniGetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetFloatField, env, obj, fieldID);
}
INLINE jdouble jniGetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID) {
return JNI_CALL(GetDoubleField, env, obj, fieldID);
}
INLINE void jniSetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject val) {
JNI_CALL(SetObjectField, env, obj, fieldID, val);
}
INLINE void jniSetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val) {
JNI_CALL(SetBooleanField, env, obj, fieldID, val);
}
INLINE void jniSetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val) {
JNI_CALL(SetByteField, env, obj, fieldID, val);
}
INLINE void jniSetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar val) {
JNI_CALL(SetCharField, env, obj, fieldID, val);
}
INLINE void jniSetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort val) {
JNI_CALL(SetShortField, env, obj, fieldID, val);
}
INLINE void jniSetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint val) {
JNI_CALL(SetIntField, env, obj, fieldID, val);
}
INLINE void jniSetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong val) {
JNI_CALL(SetLongField, env, obj, fieldID, val);
}
INLINE void jniSetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val) {
JNI_CALL(SetFloatField, env, obj, fieldID, val);
}
INLINE void jniSetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val) {
JNI_CALL(SetDoubleField, env, obj, fieldID, val);
}
INLINE jmethodID jniGetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
return JNI_CALL(GetStaticMethodID, env, clazz, name, sig);
}
INLINE jobject jniCallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jobject result;
va_start(args, methodID);
result = JNI_CALL(CallStaticObjectMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jobject jniCallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticObjectMethodV, env, clazz, methodID, args);
}
INLINE jobject jniCallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticObjectMethodA, env, clazz, methodID, args);
}
INLINE jboolean jniCallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jboolean result;
va_start(args, methodID);
result = JNI_CALL(CallStaticBooleanMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jboolean jniCallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticBooleanMethodV, env, clazz, methodID, args);
}
INLINE jboolean jniCallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticBooleanMethodA, env, clazz, methodID, args);
}
INLINE jbyte jniCallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jbyte result;
va_start(args, methodID);
result = JNI_CALL(CallStaticByteMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jbyte jniCallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticByteMethodV, env, clazz, methodID, args);
}
INLINE jbyte jniCallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticByteMethodA, env, clazz, methodID, args);
}
INLINE jchar jniCallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jchar result;
va_start(args, methodID);
result = JNI_CALL(CallStaticCharMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jchar jniCallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticCharMethodV, env, clazz, methodID, args);
}
INLINE jchar jniCallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticCharMethodA, env, clazz, methodID, args);
}
INLINE jshort jniCallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jshort result;
va_start(args, methodID);
result = JNI_CALL(CallStaticShortMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jshort jniCallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticShortMethodV, env, clazz, methodID, args);
}
INLINE jshort jniCallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticShortMethodA, env, clazz, methodID, args);
}
INLINE jint jniCallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jint result;
va_start(args, methodID);
result = JNI_CALL(CallStaticIntMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jint jniCallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticIntMethodV, env, clazz, methodID, args);
}
INLINE jint jniCallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticIntMethodA, env, clazz, methodID, args);
}
INLINE jlong jniCallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jlong result;
va_start(args, methodID);
result = JNI_CALL(CallStaticLongMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jlong jniCallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticLongMethodV, env, clazz, methodID, args);
}
INLINE jlong jniCallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticLongMethodA, env, clazz, methodID, args);
}
INLINE jfloat jniCallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jfloat result;
va_start(args, methodID);
result = JNI_CALL(CallStaticFloatMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jfloat jniCallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticFloatMethodV, env, clazz, methodID, args);
}
INLINE jfloat jniCallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticFloatMethodA, env, clazz, methodID, args);
}
INLINE jdouble jniCallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
va_list args;
jdouble result;
va_start(args, methodID);
result = JNI_CALL(CallStaticDoubleMethodV, env, clazz, methodID, args);
va_end(args);
return result;
}
INLINE jdouble jniCallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) {
return JNI_CALL(CallStaticDoubleMethodV, env, clazz, methodID, args);
}
INLINE jdouble jniCallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) {
return JNI_CALL(CallStaticDoubleMethodA, env, clazz, methodID, args);
}
INLINE void jniCallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...) {
va_list args;
va_start(args, methodID);
JNI_CALL(CallStaticVoidMethodV, env, cls, methodID, args);
va_end(args);
}
INLINE void jniCallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args) {
JNI_CALL(CallStaticVoidMethodV, env, cls, methodID, args);
}
INLINE void jniCallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args) {
JNI_CALL(CallStaticVoidMethodA, env, cls, methodID, args);
}
INLINE jfieldID jniGetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
return JNI_CALL(GetStaticFieldID, env, clazz, name, sig);
}
INLINE jobject jniGetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticObjectField, env, clazz, fieldID);
}
INLINE jboolean jniGetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticBooleanField, env, clazz, fieldID);
}
INLINE jbyte jniGetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticByteField, env, clazz, fieldID);
}
INLINE jchar jniGetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticCharField, env, clazz, fieldID);
}
INLINE jshort jniGetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticShortField, env, clazz, fieldID);
}
INLINE jint jniGetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticIntField, env, clazz, fieldID);
}
INLINE jlong jniGetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticLongField, env, clazz, fieldID);
}
INLINE jfloat jniGetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticFloatField, env, clazz, fieldID);
}
INLINE jdouble jniGetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
return JNI_CALL(GetStaticDoubleField, env, clazz, fieldID);
}
INLINE void jniSetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value) {
JNI_CALL(SetStaticObjectField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value) {
JNI_CALL(SetStaticBooleanField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value) {
JNI_CALL(SetStaticByteField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value) {
JNI_CALL(SetStaticCharField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value) {
JNI_CALL(SetStaticShortField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value) {
JNI_CALL(SetStaticIntField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value) {
JNI_CALL(SetStaticLongField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value) {
JNI_CALL(SetStaticFloatField, env, clazz, fieldID, value);
}
INLINE void jniSetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value) {
JNI_CALL(SetStaticDoubleField, env, clazz, fieldID, value);
}
INLINE jstring jniNewString(JNIEnv *env, const jchar *unicode, jsize len) {
return JNI_CALL(NewString, env, unicode, len);
}
INLINE jsize jniGetStringLength(JNIEnv *env, jstring str) {
return JNI_CALL(GetStringLength, env, str);
}
INLINE const jchar *jniGetStringChars(JNIEnv *env, jstring str, jboolean *isCopy) {
return JNI_CALL(GetStringChars, env, str, isCopy);
}
INLINE void jniReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars) {
JNI_CALL(ReleaseStringChars, env, str, chars);
}
INLINE jstring jniNewStringUTF(JNIEnv *env, const char *utf) {
return JNI_CALL(NewStringUTF, env, utf);
}
INLINE jsize jniGetStringUTFLength(JNIEnv *env, jstring str) {
return JNI_CALL(GetStringUTFLength, env, str);
}
INLINE const char* jniGetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy) {
return JNI_CALL(GetStringUTFChars, env, str, isCopy);
}
INLINE void jniReleaseStringUTFChars(JNIEnv *env, jstring str, const char* chars) {
JNI_CALL(ReleaseStringUTFChars, env, str, chars);
}
INLINE jsize jniGetArrayLength(JNIEnv *env, jarray array) {
return JNI_CALL(GetArrayLength, env, array);
}
/*
NewObjectArray
jobjectArray NewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement);
Constructs a new array holding objects in class elementClass. All elements are initially set to initialElement.
LINKAGE:
Index 172 in the JNIEnv interface function table.
PARAMETERS:
env: the JNI interface pointer.
length: array size.
elementClass: array element class.
initialElement: initialization value.
RETURNS:
Returns a Java array object, or NULL if the array cannot be constructed.
THROWS:
OutOfMemoryError: if the system runs out of memory.
*/
INLINE jobjectArray jniNewObjectArray(JNIEnv *env, jsize len, jclass clazz, jobject init) {
return JNI_CALL(NewObjectArray, env, len, clazz, init);
}
INLINE jobject jniGetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) {
return JNI_CALL(GetObjectArrayElement, env, array, index);
}
INLINE void jniSetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val) {
JNI_CALL(SetObjectArrayElement, env, array, index, val);
}
INLINE jbooleanArray jniNewBooleanArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewBooleanArray, env, len);
}
INLINE jbyteArray jniNewByteArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewByteArray, env, len);
}
INLINE jcharArray jniNewCharArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewCharArray, env, len);
}
INLINE jshortArray jniNewShortArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewShortArray, env, len);
}
INLINE jintArray jniNewIntArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewIntArray, env, len);
}
INLINE jlongArray jniNewLongArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewLongArray, env, len);
}
INLINE jfloatArray jniNewFloatArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewFloatArray, env, len);
}
INLINE jdoubleArray jniNewDoubleArray(JNIEnv *env, jsize len) {
return JNI_CALL(NewDoubleArray, env, len);
}
INLINE jboolean *jniGetBooleanArrayElements(JNIEnv *env, jbooleanArray array, jboolean *isCopy) {
return JNI_CALL(GetBooleanArrayElements, env, array, isCopy);
}
INLINE jbyte *jniGetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy) {
return JNI_CALL(GetByteArrayElements, env, array, isCopy);
}
INLINE jchar *jniGetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy) {
return JNI_CALL(GetCharArrayElements, env, array, isCopy);
}
INLINE jshort *jniGetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy) {
return JNI_CALL(GetShortArrayElements, env, array, isCopy);
}
INLINE jint *jniGetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy) {
return JNI_CALL(GetIntArrayElements, env, array, isCopy);
}
INLINE jlong *jniGetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy) {
return JNI_CALL(GetLongArrayElements, env, array, isCopy);
}
INLINE jfloat *jniGetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy) {
return JNI_CALL(GetFloatArrayElements, env, array, isCopy);
}
INLINE jdouble *jniGetDoubleArrayElements(JNIEnv *env, jdoubleArray array, jboolean *isCopy) {
return JNI_CALL(GetDoubleArrayElements, env, array, isCopy);
}
INLINE void jniReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode) {
JNI_CALL(ReleaseBooleanArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems, jint mode) {
JNI_CALL(ReleaseByteArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems, jint mode) {
JNI_CALL(ReleaseCharArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems, jint mode) {
JNI_CALL(ReleaseShortArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems, jint mode) {
JNI_CALL(ReleaseIntArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems, jint mode) {
JNI_CALL(ReleaseLongArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems, jint mode) {
JNI_CALL(ReleaseFloatArrayElements, env, array, elems, mode);
}
INLINE void jniReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode) {
JNI_CALL(ReleaseDoubleArrayElements, env, array, elems, mode);
}
INLINE void jniGetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start, jsize len, jboolean *buf) {
JNI_CALL(GetBooleanArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf) {
JNI_CALL(GetByteArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf) {
JNI_CALL(GetCharArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf) {
JNI_CALL(GetShortArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf) {
JNI_CALL(GetIntArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf) {
JNI_CALL(GetLongArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf) {
JNI_CALL(GetFloatArrayRegion, env, array, start, len, buf);
}
INLINE void jniGetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf) {
JNI_CALL(GetDoubleArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start, jsize len, const jboolean *buf) {
JNI_CALL(SetBooleanArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf) {
JNI_CALL(SetByteArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf) {
JNI_CALL(SetCharArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf) {
JNI_CALL(SetShortArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf) {
JNI_CALL(SetIntArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf) {
JNI_CALL(SetLongArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf) {
JNI_CALL(SetFloatArrayRegion, env, array, start, len, buf);
}
INLINE void jniSetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf) {
JNI_CALL(SetDoubleArrayRegion, env, array, start, len, buf);
}
INLINE jint jniRegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods) {
return JNI_CALL(RegisterNatives, env, clazz, methods, nMethods);
}
INLINE jint jniUnregisterNatives(JNIEnv *env, jclass clazz) {
return JNI_CALL(UnregisterNatives, env, clazz);
}
/**
* jint MonitorEnter(JNIEnv *env, jobject obj);
*
* Enters the monitor associated with the underlying Java object referred to by obj.
*
* Enters the monitor associated with the object referred to by obj. The obj reference must not be NULL.
* Each Java object has a monitor associated with it. If the current thread already owns the monitor associated with obj, it increments a
* counter in the monitor indicating the number of times this thread has entered the monitor. If the monitor associated with obj is not owned
* by any thread, the current thread becomes the owner of the monitor, setting the entry count of this monitor to 1. If another thread already
* owns the monitor associated with obj, the current thread waits until the monitor is released, then tries again to gain ownership.
*
* A monitor entered through a MonitorEnter JNI function call cannot be exited using the monitorexit Java virtual machine instruction or a
* synchronized method return. A MonitorEnter JNI function call and a monitorenter Java virtual machine instruction may race to enter the
* monitor associated with the same object.
*
* To avoid deadlocks, a monitor entered through a MonitorEnter JNI function call must be exited using the MonitorExit JNI call, unless the
* DetachCurrentThread call is used to implicitly release JNI monitors.
*
*
* LINKAGE: Index 217 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* obj: a normal Java object or class object.
*
* RETURNS:
* Returns “0” on success; returns a negative value on failure.
*/
INLINE jint jniMonitorEnter(JNIEnv *env, jobject obj) {
return JNI_CALL(MonitorEnter, env, obj);
}
/**
* jint MonitorExit(JNIEnv *env, jobject obj);
*
* The current thread must be the owner of the monitor associated with the underlying Java object referred to by obj. The thread decrements the counter
* indicating the number of times it has entered this monitor. If the value of the counter becomes zero, the current thread releases the monitor.
*
* Native code must not use MonitorExit to exit a monitor entered through a synchronized method or a monitorenter Java virtual machine instruction.
*
*
* LINKAGE: Index 218 in the JNIEnv interface function table.
*
* PARAMETERS:
* env: the JNI interface pointer.
* obj: a normal Java object or class object.
*
* RETURNS:
* Returns “0” on success; returns a negative value on failure.
*
* EXCEPTIONS:
* IllegalMonitorStateException: if the current thread does not own the monitor.
*/
INLINE jint jniMonitorExit(JNIEnv *env, jobject obj) {
return JNI_CALL(MonitorExit, env, obj);
}
INLINE jint jniGetJavaVM(JNIEnv *env, JavaVM **vm) {
return JNI_CALL(GetJavaVM, env, vm);
}
INLINE void jniGetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf) {
JNI_CALL(GetStringRegion, env, str, start, len, buf);
}
INLINE void jniGetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf) {
JNI_CALL(GetStringUTFRegion, env, str, start, len, buf);
}
INLINE void *jniGetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy) {
return JNI_CALL(GetPrimitiveArrayCritical, env, array, isCopy);
}
INLINE void jniReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode) {
JNI_CALL(ReleasePrimitiveArrayCritical, env, array, carray, mode);
}
INLINE const jchar *jniGetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy) {
return JNI_CALL(GetStringCritical, env, string, isCopy);
}
INLINE void jniReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring) {
JNI_CALL(ReleaseStringCritical, env, string, cstring);
}
INLINE jweak jniNewWeakGlobalRef(JNIEnv *env, jobject obj) {
return JNI_CALL(NewWeakGlobalRef, env, obj);
}
INLINE void jniDeleteWeakGlobalRef(JNIEnv *env, jweak ref) {
JNI_CALL(DeleteWeakGlobalRef, env, ref);
}
/*
* We introduce a convenience function to check for pending exceptions without creating
* a local reference to the exception object.
*
* jboolean ExceptionCheck(JNIEnv *env);
*
* Returns JNI_TRUE when there is a pending exception; otherwise, returns JNI_FALSE.
*
* LINKAGE: Index 228 in the JNIEnv interface function table.
* SINCE: JDK/JRE 1.2
*/
INLINE jboolean jniExceptionCheck(JNIEnv *env) {
return JNI_CALL(ExceptionCheck, env);
}
INLINE jobject jniNewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity) {
return JNI_CALL(NewDirectByteBuffer, env, address, capacity);
}
INLINE void* jniGetDirectBufferAddress(JNIEnv *env, jobject buf) {
return JNI_CALL(GetDirectBufferAddress, env, buf);
}
INLINE jlong jniGetDirectBufferCapacity(JNIEnv *env, jobject buf) {
return JNI_CALL(GetDirectBufferCapacity, env, buf);
}
INLINE jobjectRefType jniGetObjectRefType(JNIEnv *env, jobject obj) {
return JNI_CALL(GetObjectRefType, env, obj);
}
#define MSG_SIZE 1024
// Avoid typos in class names
#define EIllegalArgument "java/lang/IllegalArgumentException"
#define EOutOfMemory "java/lang/OutOfMemoryError"
#define EUnsatisfiedLink "java/lang/UnsatisfiedLinkError"
#define EIllegalState "java/lang/IllegalStateException"
#define EUnsupportedOperation "java/lang/UnsupportedOperationException"
#define ERuntime "java/lang/RuntimeException"
#define EError "java/lang/Error"
#endif /* _Included_JNI */
/*
* JnToy.cpp
*
* Created on: 2016-4-7
* Author: fangss
*/
#include <stdio.h>
#include "JnToy.h"
// Implementation of native method parseBytes() of JnToy class
JNIEXPORT jint JNICALL
Java_JnToy_parseBytes(JNIEnv *, jobject, jbyteArray) {
printf("Hello World!\n");
return 0;
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JnToy */
#ifndef _Included_JnToy
#define _Included_JnToy
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JnToy
* Method: parseBytes
* Signature: ([B)I
*/
JNIEXPORT jint JNICALL Java_JnToy_parseBytes
(JNIEnv *, jobject, jbyteArray);
#ifdef __cplusplus
}
#endif
#endif
import java.lang.reflect.Field;
public class JnToy {
static {
String lib_path = System.getProperty("java.library.path");
System.out.println("java.library.path = " + lib_path);
System.out.println("os.arch = " + System.getProperty("os.arch"));
// java -version
// Sun has a Java System property to determine the bitness of the JVM: 32 or 64:
// http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_detection
// the system property sun.arch.data.model has the value "32", "64", or "unknown"
// sun.arch.data.model=32 // 32 bit JVM
// sun.arch.data.model=64 // 64 bit JVM
System.out.println("sun.arch.data.model = " + System.getProperty("sun.arch.data.model"));
try {
// JToy.dll (Windows) or libJToy.so (Unixes)
System.loadLibrary("JnToy"); // Notice lack of lib prefix
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
}
}
private native int parseBytes(byte[] bytes);
public static void main(String[] args) {
// System.loadLibrary("JToy");
JnToy sample = new JnToy();
System.out.println("parseBytes: " + sample.parseBytes(null));
}
private static void syspath(String path) {
System.out.println(JnToy.class.getResource(""));
System.setProperty("java.library.path", path);
// set sys_paths to null
Field sysPathsField;
try {
sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
#include <iostream>
using namespace std;
#if defined(_WIN32) || defined(WIN32) || defined(__WIN32) || defined(__WIN32__) || defined(_WIN64)
# ifdef _MSC_VER
# include <malloc.h> // For alloca(). #define alloca _alloca
# pragma warning( disable : 4152 ) /* function/data conversion */
# pragma warning( disable : 4054 ) /* cast function pointer to data pointer */
# pragma warning( disable : 4055 ) /* cast data pointer to function pointer */
# pragma warning( disable : 4204 ) /* structure initializer */
# pragma warning( disable : 4710 ) /* swprintf not inlined */
# pragma warning( disable : 4201 ) /* nameless struct/union (jni_md.h) */
# else
# ifdef USE_GCC_COMPLIER
# undef alloca
# define alloca(size) ((void*)0)
# endif
# endif
#endif
#ifdef NDEBUG
# define assert(condition) ((void)0)
#else
#include <assert.h>
// #define assert(condition) /*implementation defined*/
void asserts(int expr){ assert(expr); }
void asserts(int expr, const char* msg){ assert(expr); }
#endif
/* @see https://en.wikipedia.org/wiki/Offsetof */
// Allow for VisualGDB
#if !defined(offsetof)
# ifdef __compiler_offsetof
# define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
# else
# ifdef __cplusplus
# define offsetof(s, m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
# else
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
# endif
# endif
#endif
/* [Amazing facts about alignment](http://www.wambold.com/Martin/writings/alignof.html)
* [honor alignment requirements](http://stackoverflow.com/questions/11545153/why-doesnt-gcc-honor-alignment-requirements)
*/
#ifdef __cplusplus
template<typename T> struct alignment_trick { char c; T member; };
# define malignof(type) offsetof (alignment_trick<type>, member)
#else
# define malignof(TYPE) offsetof (struct { char c; TYPE member; }, member)
#endif
/* http://stackoverflow.com/questions/3553296/c-sizeof-single-struct-member */
#define msizeof(type, member) sizeof(((type *)0)->member)
// STATIC_CONSTANT workaround @see BOOST_STATIC_CONSTANT-------------------//
// On compilers which don't allow in-class initialization of static integral
// constant members, we must use enums as a workaround if we want the constants
// to be available at compile-time. This macro gives us a convenient way to
// declare such constants.
//@see [std::integral_constant](http://en.cppreference.com/w/cpp/types/integral_constant)
# ifdef NO_INCLASS_MEMBER_INITIALIZATION
# define STATIC_CONSTANT(type, assignment) enum { assignment }
# else
# define STATIC_CONSTANT(type, assignment) static const type assignment
# endif
//Returns the binary (base-2) logarithm of x.计算以2为底的对数log2(N)
template<int N, bool checkPowerOfTwo = false> class static_ilog2{
static_assert(!checkPowerOfTwo || (N > 0 && !(N & (N - 1))), "Not a power of 2");
public:
STATIC_CONSTANT(size_t, value = static_ilog2<N / 2>::value + 1);
};
template<> struct static_ilog2<1>{ STATIC_CONSTANT(size_t, value = 0); };
template<> struct static_ilog2<0>{ };
/* fundamental types */
enum META_TYPE{
MT_FLTL = -7, // long double
MT_FLT64 = -6,// -6, double 64bits
MT_FLT32 = -5,// -5, float 32bits
// MT_ARRAY = -4,
// MT_STRUCT = -3,
MT_VOID = 0,//
MT_ARRAY,// 1, Composite type
MT_STRUCT,// 2, Composite type
MT_INT8, // 3(8=2^3), char, int8_t, uint8_t
MT_INT16, // 4(2bytes = 16bits = 2^4bits)
MT_INT32, // 5(64=2^5), int, long, char*, type* on 32bits machine, int32_t, uint32_t;
MT_INT64 // 6(64=2^6), char*, type* on 64bits machine, int64_t, uint64_t;
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900 // Visual Studio 2015
# define CONSTEXPR constexpr
# define HAS_CONSTEXPR
#else
# define CONSTEXPR
#endif
// It's disallowed to overload a class template, but a function template overload is allowed.
// ```
// template<size_t N> struct TypeId{ enum{ value = N }; };
// template<typename T> struct TypeId{ enum{ value = sizeof(T) }; }; // error C3855: “TypeId”: 模板 参数“N”与声明不兼容
//
// template<size_t N> int foo(){ return N; }
// template<typename T = int> int foo(){ return sizeof(T); } //ok
//```
// [class templates overload](http://stackoverflow.com/questions/11968994/why-is-it-not-possible-to-overload-class-templates)
// [Compiler Error C3855-'class': type parameter 'param' is incompatible with the declaration](https://msdn.microsoft.com/library/9146h07h.aspx)
template<size_t typesize> CONSTEXPR META_TYPE metatypeid(){
switch (typesize){
case 1: return MT_INT8;
case 2: return MT_INT16;
case 4: return MT_INT32;
case 8: return MT_INT64;
default:
static_assert(0 > typesize, "not unsupported simple type size");
return MT_VOID;
}
}
template<typename T> CONSTEXPR META_TYPE metatypeid(){ return metatypeid<sizeof(T)>(); }
template<> CONSTEXPR META_TYPE metatypeid<float>(){ return MT_FLT32; }
template<> CONSTEXPR META_TYPE metatypeid<double>(){ return MT_FLT64; }
template<> CONSTEXPR META_TYPE metatypeid<long double>(){ return MT_FLTL; }
typedef struct _type_t type_t;
typedef struct _array_type_t array_type_t;
typedef struct _struct_type_t struct_type_t;
struct _type_t{
unsigned int size;
/* gcc char default unsigned, vc signed? */
signed char type;
/*
naturally aligned.
MSDN Valid entries are integer powers of two from 1 to 8192
http://en.cppreference.com/w/cpp/types/max_align_t
*/
unsigned char alignment;
union{
/* the number of members of a structure */
unsigned short membership;
/** the number of dimensions of a multi-dimensional array(called an n-dimensional array of some type)*/
unsigned short dimesions;
unsigned short arr_dim_num;
};
};
template<typename T> struct ilog2_alignof{
STATIC_CONSTANT(size_t, alignment = malignof(T));
STATIC_CONSTANT(size_t, value = static_ilog2<alignment>::value);
};
#define T_DEF(VAR_NAME, MT_TYPE, C_TYPE) type_t VAR_NAME = { sizeof(C_TYPE), MT_TYPE, ilog2_alignof<C_TYPE>::value }
#define PRINT_T_DEF(VAR) printf("{.size = %2u, .type = %2d, .alignment = %2u(2^%u)} = %s\n", (VAR).size, (VAR).type, 1 << (VAR).alignment, (VAR).alignment, #VAR)
T_DEF(T_FLTL, MT_FLTL, long double);
T_DEF(T_FLT64, MT_FLT64, double);
T_DEF(T_FLT32, MT_FLT32, float);
T_DEF(T_INT8, MT_INT8, int8_t);
T_DEF(T_INT16, MT_INT16, int16_t);
T_DEF(T_INT32, MT_INT32, int32_t);
T_DEF(T_INT64, MT_INT64, int64_t);
/* #type is MT_ARRAY*/
struct _array_type_t : public type_t
{
type_t* component;
union{
/* the number of a single-dimensional array, if #ndims = 1 */
unsigned int length;
/* a tuple of the lengths of dimensions for a multi-dimensional array, if #arr_dims_num > 1 */
unsigned int *lengths;
};
};
struct _struct_type_t : public type_t
{
type_t** members;
};
typedef union {
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
float f;
double d;
void *p;
} value_t;
void printValue(value_t &v){
cout << "u8:" << (int)v.u8 << ", u16:" << v.u16 << ", u32:" << v.u32
<< ", u64:" << v.u64 << ", f:" << v.f << ", d:" << v.d
<< ", p:" << v.p << endl;
}
void printValueTest(){
value_t v;
memset(&v, 0, sizeof v);
v.u8 = 8;
printValue(v);
v.u16 = 16;
printValue(v);
v.u32 = 32;
printValue(v);
v.u64 = 64;
printValue(v);
v.f = 22.22f;
printValue(v);
v.d = 66.66;
printValue(v);
}
template<typename Type, int Size>
void printArray(Type const(&array)[Size]) {
for (int index = 0; index < Size; index++)
std::cout << array[index] << std::endl;
}
template<typename Type>
void printArray(Type* array, int Size) {
for (int index = 0; index < Size; index++)
std::cout << array[index] << std::endl;
}
/*
error: template argument 'sizeof (_Type)' involves template parameter(s)
A partially specialized non-type argument expression shall not involve a template parameter of the
partial specialization except when the argument expression is a simple identifier.
http://stackoverflow.com/questions/8147010/is-sizeof-allowed-in-template-arguments-for-specialization
http://en.cppreference.com/w/cpp/language/partial_specialization#The_argument_list
5) Non-type argument expression cannot use the name of the template parameter except when it is
exactly the name of the template parameter
*/
//template<typename _Type> struct mt<_Type, sizeof(_Type)>{ };
// primary template
template<size_t _Size> struct metatype_int_of{ };
template<typename _Type> struct metatype_of{
static const type_t& ref;
static const type_t* ptr;
};
template<typename _Type> const type_t& metatype_of<_Type>::ref = metatype_int_of<sizeof(_Type)>::ref;
template<typename _Type> const type_t* metatype_of<_Type>::ptr = metatype_int_of<sizeof(_Type)>::ptr;
//```
// //[variable template](http://en.cppreference.com/w/cpp/language/variable_template)
// template<size_t _Size> static const type_t* TT_PTR;
// template<> static const type_t* TT_PTR<1> = &T_INT8;
// template<> static const type_t* TT_PTR<2> = &T_INT16;
//```
//[Support For C++11/14/17 Features (Modern C++)](https://msdn.microsoft.com/en-us/library/hh567368.aspx)
#if !defined(_MSC_VER) || _MSC_VER >= 1900 // Visual Studio 2015
# define DEF_INT_METATYPE_OF(SIZE, INT_NUM) template<> struct metatype_int_of<SIZE>{ \
static constexpr const type_t& ref = INT_NUM; \
static constexpr const type_t* ptr = &INT_NUM; \
};
# define DEF_METATYPE_OF(TYPE, INT_NUM) template<> struct metatype_of<TYPE>{ \
static constexpr const type_t& ref = INT_NUM; \
static constexpr const type_t* ptr = &INT_NUM; \
};
#else
// specialization macro of the template metatype_int_of where _Size is SIZE
#define DEF_INT_METATYPE_OF(SIZE, INT_NUM) template<> struct metatype_int_of<SIZE>{ \
static const type_t& ref; \
static const type_t* ptr; \
}; \
const type_t& metatype_int_of<SIZE>::ref = INT_NUM; \
const type_t* metatype_int_of<SIZE>::ptr = &INT_NUM
// specialization macro of the template metatype_of where _TYPE is TYPE
#define DEF_METATYPE_OF(TYPE, INT_NUM) template<> struct metatype_of<TYPE>{ \
static const type_t& ref; \
static const type_t* ptr; \
}; \
const type_t& metatype_of<TYPE>::ref = INT_NUM; \
const type_t* metatype_of<TYPE>::ptr = &INT_NUM
#endif
DEF_INT_METATYPE_OF(1, T_INT8);
DEF_INT_METATYPE_OF(2, T_INT16);
DEF_INT_METATYPE_OF(4, T_INT32);
DEF_INT_METATYPE_OF(8, T_INT64);
DEF_METATYPE_OF(float, T_FLT32);
DEF_METATYPE_OF(double, T_FLT64);
DEF_METATYPE_OF(long double, T_FLTL);
void printMetaTypeTest(){
printf("%zu\n", sizeof(type_t));
///metatypeid<100>::value;
PRINT_T_DEF(T_FLTL);
PRINT_T_DEF(T_FLT64);
PRINT_T_DEF(T_FLT32);
PRINT_T_DEF(T_INT8);
PRINT_T_DEF(T_INT16);
PRINT_T_DEF(T_INT32);
PRINT_T_DEF(T_INT64);
//
printf("\n");
PRINT_T_DEF(metatype_of<char>::ref);
PRINT_T_DEF(metatype_of<unsigned>::ref);
PRINT_T_DEF(*metatype_of<uint64_t>::ptr);
PRINT_T_DEF(*metatype_of<float>::ptr);
PRINT_T_DEF(*metatype_of<double>::ptr);
printf("\n");
// The C++ compiler treats variables of type char, signed char
//, and unsigned char as having different types. Variables of
//type char are promoted to int as if they are type signed char
//by default, unless the /J compilation option is used. In this
//case they are treated as type unsigned char and are promoted
//to int without sign extension.
//https://msdn.microsoft.com/en-us/library/cc953fe1.aspx
char c = -1;
printf("%d\n", c);
}
int main()
{
// printValueTest();
//uint16_t u16_array_src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
//float f32_array_dst[9] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f };
//toJArray(TYPE64, u16_array_src, 8, TYPE16);
//toJArray(TYPE_FLOAT32, u16_array_src, 8, TYPE16);
//toJArray(TYPE_FLOAT64, f32_array_dst);//, 8, TYPE_FLOAT32);
// printValueTest();
//uint16_t u16_array_src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
//float f32_array_dst[9] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f };
//toJArray(TYPE64, u16_array_src, 8, TYPE16);
//toJArray(TYPE_FLOAT32, u16_array_src, 8, TYPE16);
//toJArray(TYPE_FLOAT64, f32_array_dst);//, 8, TYPE_FLOAT32);
printMetaTypeTest();
const type_t *mt_type_t_elements[4];
struct_type_t mt_type_t;
mt_type_t.members = const_cast<type_t **>(mt_type_t_elements);
mt_type_t.membership = 4;
mt_type_t_elements[0] = metatype_of<unsigned int>::ptr;
mt_type_t_elements[1] = metatype_of<unsigned char>::ptr;
mt_type_t_elements[2] = metatype_of<unsigned char>::ptr;
mt_type_t_elements[3] = metatype_of<unsigned short>::ptr;
#ifdef _MSC_VER
getchar();
#endif
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment