java JNI 调用c++编程

  • 一,DLL_Source 文件为第三方提供的dll
  • 二,Dll_test 文件 自己封装的dll
  • 三,testDll 文件  javaweb 程序
  • 四,第三方dll接口文档

Call_dll.java文件的代码如下: 

package com.testDll;

import com.sun.org.apache.xpath.internal.operations.Bool;

//import com.sun.jna.ptr.IntByReference;

public class Call_dll {
    static
    {
        System.loadLibrary( "Dll_test" ); //寮曠敤鐨刣ll鏂囦欢  鑷繁灏佽鐨�
    }
    
    public native int ZZInitFaceMgr();
    
    public native String ZZGetFaceTemplFromFile(String fileName);

    public native int ZZCompareFace(String feature1, String feature2, int threshold);
    
    public native int ZZCompareFacePic(String fileName1, String fileName2, int threshold);
}
 

  • 编写Call_dll,java文件调用自己封装的dll文件 Dll_test
  • 打开dos命令窗口 
  1. 访问java程序所在路径 并进入 .Java 文件路径  用 javac  *.java 编译所有java程序
  2. 进入程序src目录下  用 javah -jni com.testDll.Call_dll 命令 得到com_testDll_Call_dll.h 文件
  3. 把com_testDll_Call_dll.h 文件放在java程序根目录下

生成后的com_testDll_Call_dll.h代码如下:

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

#ifndef _Included_com_testDll_Call_dll
#define _Included_com_testDll_Call_dll
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_testDll_Call_dll
 * Method:    ZZInitFaceMgr
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_testDll_Call_1dll_ZZInitFaceMgr
  (JNIEnv *, jobject);

/*
 * Class:     com_testDll_Call_dll
 * Method:    ZZGetFaceTemplFromFile
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_testDll_Call_1dll_ZZGetFaceTemplFromFile
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_testDll_Call_dll
 * Method:    ZZCompareFace
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)I
 */
JNIEXPORT jint JNICALL Java_com_testDll_Call_1dll_ZZCompareFace
  (JNIEnv *, jobject, jstring, jstring, jint);

/*
 * Class:     com_testDll_Call_dll
 * Method:    ZZCompareFacePic
 * Signature: (Ljava/lang/String;Ljava/lang/String;I)I
 */
JNIEXPORT jint JNICALL Java_com_testDll_Call_1dll_ZZCompareFacePic
  (JNIEnv *, jobject, jstring, jstring, jint);

#ifdef __cplusplus
}
#endif
#endif
 

八.创建C++ 程序 Dll_test  (我用的是vs2010)

创建好C++工程后

  1. 把java生成的com_testDll_Call_dll.h 放在E:\vsProjects\Dll_test1\Dll_test1 文件下
  2. 在vs中引入
  3. 之后在Dll_test.cpp中引入 #include "com_testDll_Call_dll.h"  之后编译程序 会报错 1>e:\vsprojects\dll_test1\dll_test1\com_testdll_call_dll.h(2): fatal error C1083: Cannot open include file: 'jni.h': No such file or directory

     没有找到  jni.h  这个文件 

    因为我们少了一个步骤:选中程序右击属性

  4. 这里引入了jdk中所需的 .h 文件 以后编译成功

  5. 把第三方提供的 .dll  和 .lib 文件 放到 Debug 文件下
  6. 之后用步骤2的方式引入 然后在编写 Dll_test,cpp 文件 之后Build一下

  7. 在E:\vsProjects\Dll_test1\Dll_test1\Debug 文件中 复制 Dll_test.dll 和DLL_Tutorial.dll 文件 找到 java 程序 E:\Workspaces\testDll 在这里粘贴
  8. com_testDll_Call_dll.h 头文件接口代码C++实现

  9. // Dll_test.cpp : Defines the exported functions for the DLL application.
    //
    #include <afxwin.h>
    #include "string.h"
    #include "ZZLibrary.h"
    #include "stdafx.h"
    #include <Windows.h>
    #include "com_testDll_Call_dll.h"
    #include <iostream>

    using namespace std;


    typedef struct _FreImage
    {
        int nSize; // FreImage 结构大小,即sizeof(FreImage)
    }FreImage;
    //    3    IntelliSense: "const char *" 类型的实参与 "LPCWSTR" 类型的形参不兼容    d:\work\doorcontrolsys\javacpp\dll_test\dll_test\dll_test.cpp    64    14    Dll_test

    //typedef jbyteArray (*GetFaceTemplFromFile)(LPCWSTR fileName);
    //char* str

    typedef jbyteArray (*GetFaceTemplFromFile)(const char* fileName);

    typedef BOOL (*InitFaceMgr)();

    extern "C"
    {
        HMODULE dllHandle = LoadLibrary(TEXT("ZZLibrary.dll"));//商家提供的库文件

        JNIEXPORT jint JNICALL Java_com_testDll_Call_1dll_ZZInitFaceMgr
            (JNIEnv *env, jobject obj)
        {

            InitFaceMgr addTest;
            addTest = (InitFaceMgr)GetProcAddress(dllHandle, "ZZInitFaceMgr");//寻找商家提供库中对应的方法名
            //BOOL retvalue=addTest();
            BOOL bl=ZZInitFaceMgr();

            //ZZDeinitFaceMgr();
            cout << bl << endl;
            //jclass objectClass = (env)->FindClass("com/testDll/FreImage");
             //序列号
            //jclass objectClass = (env)->FindClass("com/testDll/FreImage");
            // //序列号
            //jfieldID ival = (env)->GetFieldID(objectClass,"nSize","I");
            //(env)->SetBooleanField(obj, ival, retvalue);
            return bl;
        }

        char* jstringToChar(JNIEnv *env, jstring jstr) 
        {
            int length = (env)->GetStringLength(jstr);
            const jchar* jcstr = (env)->GetStringChars(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(jstr, jcstr);
            rtn[size] = 0;
            return rtn;
        }


        //char* to jstring
        jstring stoJstring(JNIEnv* env, const char* pat)
        {
            jclass strClass = env->FindClass("Ljava/lang/String;");
            jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
            jbyteArray bytes = env->NewByteArray(strlen(pat));
            env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
            jstring encoding = env->NewStringUTF("utf-8");
            return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
        }

        //BSTR jstringtoBSTR(JNIEnv* env, jstring jstrParam)
        //{
        //    jboolean isCopy = JNI_FALSE;
        //    const jchar* paramValue = env->GetStringChars(jstrParam, &isCopy);
        //    if (paramValue != NULL)
        //    {
        //        BSTR bstr = SysAllocString((OLECHAR)paramValue); //使用后记得释放:SysFreeString(bstr);
        //        if (isCopy)
        //        {
        //            env->ReleaseStringChars(jstrParam, paramValue);
        //        }
        //    }
        //}

        //jstring 转bstr
        BSTR _stdcall jstringtoBSTR(JNIEnv* env, jstring strJava)
        {
            /*jmethodID id = env->GetMethodID(testClass, "checkSendingTextMessage", "()Ljava/lang/String;");
            jstring strJava = (jstring) env->CallObjectMethod( testObject, id );*/
            BSTR retValue = NULL;
            env->ExceptionDescribe();     
            if (strJava != NULL){
                jboolean isCopy = 0;
                const jchar *data = env->GetStringChars(strJava, &isCopy);
                int length = env->GetStringLength(strJava);
                char* rtn = (char *)malloc( length*2+1 );
                int size = 0;
                size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)data, length, rtn, (length*2+1), NULL, NULL );
                if( size <= 0 )
                    return NULL;
                retValue = ::SysAllocString((WCHAR *)data);
                if (!isCopy)
                    env->ReleaseStringChars(strJava,data);

                return retValue;
            }

            return NULL;
        }

        //BSTR转string

        //
        //BSTR bstrText = ::SysAllocString(L"Test");
        //
        //string str = _com_util::ConvertBSTRToString(bstrText);  
        //
        //SysFreeString(bstrText);  

        //BSTR转char*

        //BSTR bstrText = ::SysAllocString(L"Test");
        //
        //char* lpszText = _com_util::ConvertBSTRToString(bstrText);  
        //SysFreeString(bstrText); 
        //
        //delete[] lpszText;

        //char*转BSTR

        //char* lpszText = "Test"; 
        //
        //BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText); 

        //string转BSTR

        //string str = "Test"; 
        //
        //BSTR bstrText = _com_util::ConvertStringToBSTR(str); 

        LPCWSTR stringToLPCWSTR(std::string orig)
        {
            size_t origsize = orig.length() + 1;
            const size_t newsize = 100;
            size_t convertedChars = 0;
            wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length()-1));
            mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
            return wcstring;
        }


        /*BSTR  ptr = .xxxxbyteLen(6);

        a = malloc(6+ sizeof(int));
        *((int*)a) = 6;
        return a+sizeof(int) */

        JNIEXPORT jstring JNICALL Java_com_testDll_Call_1dll_ZZGetFaceTemplFromFile
            (JNIEnv *env, jobject obj, jstring fileName)
        {
            jbyteArray jbarrayFeature1;
            //HMODULE dllHandle;
            //GetFaceTemplFromFile addTest;
            //const char* str = env->GetStringUTFChars(fileName, 0);
            const char* str = jstringToChar(env,fileName);
            //jbarrayFeature1=env->NewByteArray(100);
            char* szStr = "测试字符串";
            /*  WCHAR wszClassName[256];
            memset(wszClassName,0,sizeof(wszClassName));
            MultiByteToWideChar(CP_ACP,0,str,strlen(str)+1,wszClassName,
            sizeof(wszClassName)/sizeof(wszClassName[0]));*/
            LPCWSTR str1=stringToLPCWSTR(str);
            int length = (env)->GetStringLength(fileName);
            cout << str <<endl<< "length:"<<length<<endl;
            BSTR bstr=ZZGetFaceTemplFromFile(str1);
            char* stringss = _com_util::ConvertBSTRToString(bstr);
            //char* lpszText = _com_util::ConvertBSTRToString(bstr);  

            //env->SetObjectArrayElement(jbarrayFeature1, i, theJavaString);
            cout << "66666666"<<endl;
            // 获得字符数
            int nLen = SysStringLen(bstr);
            cout << "bstrlength:"<<nLen<<endl;
            if(bstr==NULL)
            {
                jstring encoding = env->NewStringUTF("no face");
                //string theJavaString = stoJstring(env,stringss);
                return encoding;
            }
            else
            {
                jstring theJavaString = stoJstring(env,stringss);
                dllHandle = LoadLibrary(TEXT("ZZLibrary.dll"));//商家提供的库文件
                //addTest = (GetFaceTemplFromFile)GetProcAddress(dllHandle, "ZZGetFaceTemplFromFile");//寻找商家提供库中对应的方法名
                //cout <<"wszClassName:"<< *wszClassName << endl;
                //addTest(str);
                cout <<"theJavaString:"<< theJavaString << endl;

                return theJavaString;
            }

        }

        JNIEXPORT jint JNICALL Java_com_testDll_Call_1dll_ZZCompareFacePic
            (JNIEnv *env, jobject obj, jstring fileName1, jstring fileName2, jint threshold)
        {
            const char* str = jstringToChar(env,fileName1);
            LPCWSTR str1=stringToLPCWSTR(str);
            str = jstringToChar(env,fileName2);
            LPCWSTR str2=stringToLPCWSTR(str);

            BSTR bstr1=ZZGetFaceTemplFromFile(str1);

            BSTR bstr2=ZZGetFaceTemplFromFile(str2);
            BOOL revalue=ZZCompareFace(bstr1,bstr2,threshold);
            return revalue;
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值