zoukankan      html  css  js  c++  java
  • code::Blocks生成的dll 在 java jni 调用遇到的问题

    Test.java
    __________________________________

    public class Test
    {
        public static native void p();

        public static void main(String[] args)
        {
            System.loadLibrary("TestDll");

            p();
        }
    }

    javac Test.java

    javah -jni Test    //命令生成的test.c头文件

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

    #ifndef _Included_Test
    #define _Included_Test
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     Test
     * Method:    p
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_Test_p
      (JNIEnv *, jclass);

    #ifdef __cplusplus
    }
    #endif
    #endif

     testdll.c   (将 c:jdkin下面的 jni.h 和 jni_md.h 复制到当前c程序的文件夹里)

    ________________________________

    #include "jni.h"
    #include "test.h"
    #include <stdio.h>

    JNIEXPORT void JNICALL Java_Test_p(JNIEnv *env, jobject obj)
    {
        printf("Hello world! ");
        return;
    }

    用code::Blocks生成的dll,使用DLL Export Viewer查看其函数名是Java_Test_p@8。

    cmd> java Test 抛出错误:

    java.lang.UnsatisfiedLinkError: Test.p()V

    ___________________________________________

    解决的第1种方法:

    在testdll.h文件中把"Java_Hello_p"函数前的"JNICALL"去掉,重编dll就能测试通过。(注: #define JNICALL __stdcall),网上的查到的资料如下:
    HTML code

    stdcall的调用约定意味着:1)参数从右向左压入堆栈,2)函数自身修改堆栈 3)函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸。

    ___________________________________________

    解决的第2种方法:@silenceburn (http://topic.csdn.net/u/20110216/15/d85cf526-beb9-4a36-b6c2-7ade7f1eb01d.html)

    正好手边有codeBlocks,就测试了一下,的确会有LZ说的问题,
    放狗搜了搜,是因为JNI想要VC风格的函数声明,但是CodeBlocks默认的GCC编译器生成的是GCC风格的
    需要用编译选项修改生成风格,8L的兄弟说的是对的。
    修改的位置在CodeBlocks的工程右键properties - Build Targets - Build Options - Linker Setting - Other Linker Options ,加入 -Wl,--kill-at 即可。我在我本机已经测试通过。

    ___________________________________________

    在测试通过java传字符串到c写的dll时,发现在c程序中打印出来的中文会出现乱码情况,在百度搜索后找到一个解决方法:

    #include "jni.h"
    #include "test.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>


    char* jstringToWindows( JNIEnv *env, jstring jstr );

    jstring WindowsTojstring( JNIEnv* env, char* str );


    JNIEXPORT void JNICALL Java_Test_p(JNIEnv *env, jobject obj)
    {
        printf("Hello world! ");
        return;
    }

    //通过java传字符串过来
    JNIEXPORT void JNICALL Java_Test_abcd(JNIEnv *env, jobject obj, jstring p)
    {

        const char * str = jstringToWindows( env, p );
        printf( "%s " , str);
        /*

          如果把上句改为下句,C接收Java字符串时将出现乱码:
          //const char* str = (*env)->GetStringUTFChars(env, p, 0);
          //printf("%s",str);

        */

    }

    //需要用一下2个函数做编码格式转换
    char* jstringToWindows( JNIEnv  *env, jstring jstr )

    {

        int length = (*env)->GetStringLength(env,jstr );

        const jchar* jcstr = (*env)->GetStringChars(env,jstr, 0 );

        char* rtn = (char*)malloc( length*2+1 );

        int size = 0;

        size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );

        if( size <= 0 )

            return NULL;

        (*env)->ReleaseStringChars(env,jstr, jcstr );

        rtn[size] = 0;

        return rtn;

    }


    jstring WindowsTojstring( JNIEnv* env, char* str )

    {

        jstring rtn = 0;

        int slen = strlen(str);

        unsigned short* buffer = 0;

        if( slen == 0 )

            rtn = (*env)->NewStringUTF(env,str );

        else

        {

            int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );

            buffer = malloc( length*2 + 1 );

            if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )

                rtn = (*env)->NewString( env, (jchar*)buffer, length );

        }

        if( buffer )

            free( buffer );

        return rtn;

    }

  • 相关阅读:
    创意:网络族谱
    排列组合的要点
    创意:人生记录
    纽康悖论谜题
    发财的要点
    c#4.0协变逆变的理解
    关于开发自我训练课程
    反对继承
    远离疲倦,告别非理性思维
    中国软件正版化的理想模型
  • 原文地址:https://www.cnblogs.com/personnel/p/4583059.html
Copyright © 2011-2022 走看看