JAVA JNI调用C编写的dll

本文详细介绍了Java工程如何调用C编写的DLL,包括步骤、代码实现及遇到的问题与解决方法。重点关注JNI的使用,从创建工程、编写Java代码到VS实现调用,全程指导。此外,还分享了在JNI调用过程中遇到的常见问题,如UnsatisfiedLinkError和包头问题的解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引用:jni调用dll,http://blog.sina.com.cn/s/blog_4bb52a1601012x8j.html

引用:UnsatisfiedLinkError ,http://stackoverflow.com/questions/9984961/jni-unsatisfied-link-error-cant-find-dependent-libraries

引用:包头的问题,http://1985wanggang.blog.163.com/blog/static/7763833201101011210338/

今天因为项目需要,java工程调用原来C编写的一个dll(msc.dll)。折腾了半天终于打通了,现在把流程和中间遇到的问题记录下来。

一、JAVA的JNI主要有以下几步:

1、编写java代码(CallMSC.java),定义要引用的dll中的函数

2、用javac编译CallMSC.java生成CallMSC.class。

3、用javah编译CallMSC.class,生成CallMSC.h,用于VS实现调用dll。

4、VS创建dll工程,生成jni.dll,实现CallMSC.h中的函数,并调用msc.dll。

5、java工程集成并调用msc.dll。

二、工程代码如下:

1、CallMSC.java

package com.iflytekWS.jni.callmsc;

public class CallMSC{
	static
	{
		System.load("d://JNI//BIN//msc.dll");
		System.load("d://JNI//BIN//jni.dll");
	}
	public native int MSPLogin(String usr,String pwd, String params);
	public native int MSPLogout();
	public native String MSPSearch(String params, String text);
	public native int getErrCode();
}

2、生成的CallMSC.h

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

#ifndef _Included_com_iflytekWS_jni_callmsc_CallMSC
#define _Included_com_iflytekWS_jni_callmsc_CallMSC
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_iflytekWS_jni_callmsc_CallMSC
 * Method:    MSPLogin
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_MSPLogin
  (JNIEnv *, jobject, jstring, jstring, jstring);

/*
 * Class:     com_iflytekWS_jni_callmsc_CallMSC
 * Method:    MSPLogout
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_MSPLogout
  (JNIEnv *, jobject);

/*
 * Class:     com_iflytekWS_jni_callmsc_CallMSC
 * Method:    MSPSearch
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_MSPSearch
  (JNIEnv *, jobject, jstring, jstring);

/*
 * Class:     com_iflytekWS_jni_callmsc_CallMSC
 * Method:    getErrCode
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_getErrCode
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

3、CallMSC.cpp

#include "CallMSC.h"
#include "msp_common.h"
jint errCode = 0;

JNIEXPORT jint JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_MSPLogin
(JNIEnv * env, jobject jobj, jstring jusr,jstring jpwd,jstring jstr){
	const char* usr = (env)->GetStringUTFChars(jusr, 0);
	const char* pwd = (env)->GetStringUTFChars(jpwd, 0);
	const char* params = (env)->GetStringUTFChars(jstr, 0);
	jint ret = 0;
	ret = MSPLogin(usr, pwd, params);
	env->ReleaseStringUTFChars(jusr, usr);
	env->ReleaseStringUTFChars(jpwd, pwd);
	env->ReleaseStringUTFChars(jstr, params);
	errCode = 0;
	return ret;
}


JNIEXPORT jint JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_MSPLogout
(JNIEnv *, jobject){
	jint ret = 0;
	ret = MSPLogout();
	errCode = 0;
	return ret;
}

JNIEXPORT jstring JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_MSPSearch
(JNIEnv * env, jobject jobj, jstring jparam, jstring jtxt){
	const char* params = (env)->GetStringUTFChars(jparam, 0);
	const char* text = (env)->GetStringUTFChars(jtxt, 0);
	unsigned int textlength = (unsigned int )env->GetStringUTFLength(jtxt);
	
	int ret = 0;
	const char* result = MSPSearch(params, text, &textlength, &ret);
	errCode = (jint) ret;
	jstring jrst = env->NewStringUTF(result);
	env->ReleaseStringUTFChars(jparam, params);
	env->ReleaseStringUTFChars(jtxt, text);
	return jrst;
}

JNIEXPORT jint JNICALL Java_com_iflytekWS_jni_callmsc_CallMSC_getErrCode
(JNIEnv *, jobject){
	return errCode;
}

三、使用JNI过程中遇到的问题及注意点。

1、CallMSC.java,有package时javah命令的使用。

一开始没有添加package,在CallMSC.java所在目录下很顺利使用javac和javah命令,

后来发现要有包名,添加后使用javah命令一直无法成功。提示如下,

D:\test\source\com\iflytekWS\jni\callmsc>javah CallMSC
错误:无法访问 CallMSC
错误的类文件: .\CallMSC.class
类文件包含错误的类: com.iflytekWS.jni.callmsc.CallMSC
请删除该文件或确保该文件位于正确的类路径子目录中。
这时将目录定位到整个包所在的根目录下解决。

D:\test\source\com\iflytekWS\jni\callmsc>cd D:\test\source\
D:\test\source>javah -classpath .  com.iflytekWS.jni.callmsc.CallMSC

2、JNI中jstring与const char* 相互转换时,注意GetStringUTFChars与ReleaseStringUTFChars需要配套使用。

3、Dll工程需要的jni.h可以在java JDK/include中找到,需要加载的msc.dll,msc.lib及相应头文件(本文略去)。

4、java工程调用时提示UnsatisfiedLinkError (Can't find dependent libraries)的问题。

JNI调用的dll依赖其他dll缺失,需要load进来,一开始以为和C++中调dll一样自动加载,后发现没有load msc.dll,需要手动load,System.load要指定绝对路径。load时要注意dll所依赖的库,及其引用顺序。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值