java调用vc6写的dll - 关于jni应用中的字符串参数传递



一 Java端
----------------------------------------------------------------------------------begin
import java.io.UnsupportedEncodingException;

public class DESInvokeLib {
          static { 
                      System.loadLibrary("encrypt"); 
          }

         public native static byte[] encrypt(int len, byte[] str);
         public native static byte[] decrypt(byte[] str);
 
         public static void main(String[] args) {
                    DESInvokeLib desInvokeLib = new DESInvokeLib();
  
                   String plainText = "Welcome to My Jni Test! -wangfei/n" +
                                                          "1Welcome to My Jni Test! -wangfei/n" +
                                                          "2Welcome to My Jni Test! -wangfei/n" +
                                                          "Emai: vinch.wang@gmail.com/n";
                    System.out.println("plain text is: " + plainText);
  
                    try {
                             //将String转换为字符数组
                             byte[] plainTextBytes = plainText.getBytes("ISO-8859-1");
                             int len = plainTextBytes.length;
                             System.out.println("plainTextBytes length is: " + len);

                             //先加密,再解密
                             byte[] encryptedTextBytes = desInvokeLib.encrypt(len, plainTextBytes);
                             byte[] decryptedTextBytes = desInvokeLib.decrypt(encryptedTextBytes);
   
                             //将字符数组转换为String
                             System.out.println("decryptedTextBytes length is: " +    

                             decryptedTextBytes.length);
                             String decryptedText = new String(decryptedTextBytes, "ISO-8859-1");
                             System.out.println("decryptedText is: " + decryptedText);
                            }
                             catch (UnsupportedEncodingException e) {
                                      e.printStackTrace();
                            }  
      }
}

----------------------------------------------------------------------------------end 

 

保存为DESInvokeLib.java文件, 先编译生成class文件, 再用"javah DESInvokeLib"命令生成包含dll函数导出声明的头文件"DESInvokeLib.h".  具体内容如下:
----------------------------------------------------------------------------------begin
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class DESInvokeLib */

#ifndef _Included_DESInvokeLib
#define _Included_DESInvokeLib
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     DESInvokeLib
 * Method:    encrypt
 * Signature: (I[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_DESInvokeLib_encrypt
  (JNIEnv *, jclass, jint, jbyteArray);

/*
 * Class:     DESInvokeLib
 * Method:    decrypt
 * Signature: ([B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_DESInvokeLib_decrypt
  (JNIEnv *, jclass, jbyteArray);

#ifdef __cplusplus
}
#endif
#endif
----------------------------------------------------------------------------------end

 

二 VC端

1. 在VC6的"Tool->Options"下, 添加java的库文件路径.
    如C:/JDK 1.5.0/INCLUDE  和 C:/JDK1.5.0/INCLUDE/WIN32.

2. 建立"Win32 Dynamic-Link Library"类型的空工程,  导入DES.cpp, DES.h. DESInvokeLib.h文件.
    工程名存为"encrypt".

3. 在encrypt.cpp文件内编写代码, 具体如下
----------------------------------------------------------------------------------begin
#include   "windows.h"
#include   "jni.h"                        
#include   "Des.h"                      //参照原DES加密程序
#include   "DESInvokeLib.h"     //参照原DES加密程序

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;
}


JNIEXPORT jbyteArray JNICALL Java_DESInvokeLib_encrypt
  (JNIEnv *jniEnv, jclass, jint length, jbyteArray jarrByte)
{
 //接收明文
 jbyte* pJbyte = jniEnv->GetByteArrayElements(jarrByte, 0);
 char* szByte = (char *)pJbyte;

//显示调试信息
 printf("/ncome-in: /n%s, %d/n",szByte, strlen(szByte));

 //定义Key和Buffer
 char key[] = {0,2,0,0,9,3,5,1,9,8,0,0,9,1,7};
 char buf[255];
 
 //存明文到buffer并加密
 memset( buf, 0, sizeof(buf) );
 strcpy( buf, szByte );

 /*消除java与c转换产生的多余字符*/
 buf[length] = '/0'; 

//参照原DES加密程序 
Des_Go(buf, buf, strlen(buf), key, sizeof(key), ENCRYPT);

 //生成结果并返回
 jbyteArray jarrRet = jniEnv->NewByteArray( strlen(buf) );
 strcpy( szByte, buf );

 jniEnv->SetByteArrayRegion( jarrRet, 0, strlen(buf), (jbyte *)szByte );
 jniEnv->ReleaseByteArrayElements(jarrRet, pJbyte, 0);
 return jarrRet;
}

JNIEXPORT jbyteArray JNICALL Java_DESInvokeLib_decrypt
  (JNIEnv *jniEnv, jclass, jbyteArray jarrByte)
{
 //接收
 jbyte* pJbyte = jniEnv->GetByteArrayElements(jarrByte, 0);
 char* szByte = (char *)pJbyte;

 //定义Key和Buffer
 char key[] = {0,2,0,0,9,3,5,1,9,8,0,0,9,1,7};
 char buf[256];
 
 //存明文到buffer并加密
 memset( buf, 0, sizeof(buf) );
 strcpy( buf, szByte );

 // 参照原DES加密程序 
Des_Go(buf, buf, strlen(buf), key, sizeof(key), DECRYPT);

 //生成结果并返回
 jbyteArray jarrRet = jniEnv->NewByteArray( strlen(buf) );
 strcpy( szByte, buf );

 //显示调试信息
 printf("/nout: /n%s, %d /n/n",szByte, strlen(szByte));

 jniEnv->SetByteArrayRegion( jarrRet, 0, strlen(buf), (jbyte *)szByte );
 jniEnv->ReleaseByteArrayElements(jarrRet, pJbyte, 0);
 return jarrRet;
}

----------------------------------------------------------------------------------end

4. 为方便起见,在VC6的"Project->Settings->Link->General"中,设置dll导出路径为java文件所在路径.
5. 按F7编译生成dll, 并在控制台中运行java程序, 命令如 "java DESInvokeLib", 可见结果.

 

三 小结

1.  java与vc之间传递参数, 如果是整数类型(int), 一般不会有问题, 但如果是传递字符串,则要考虑的问题较多.
 java程序编译时使用的是unicode编码, 传输时使用的是utf-8格式, 而vc6默认使用的是ansi编码.

2.  传递字符串, 在java端可以选择参数类型为 String 或者 byte[],  如果选择String,则与vc6配合做参数传递时,问题多多,还会生成不少乱码.  如果选择使用 byte[], 则处理起来容易一些,问题也要少一些.

3. 为了解决参数传递中产生的乱码问题, 所以特别在参数中加入字符串长度 len, 并在vc6收到字符串后,
用  " buf[length] = '/0'  "  命令做处理. 实践表明, 效果还比较理想.

ps: 未解决的问题
1.  在vc6中接收java传递过来的字符串参数, 会在正常字符串内容的末尾产生多余的乱码.
2.  DES程序能处理的明文长度只到255. 即buf变量定义长度.

 

参考:
1.  http://www.vckbase.com/code/viewcode.asp?id=1897
2.  http://www.iplab.cs.tsukuba.ac.jp/~liuxj/jdk1.2/zh/docs/guide/jni/spec/jniTOC.doc.html
3.  http://www.sagewire.org/java-programmer/JNI-DLL-VC-173069.aspx

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值