java向C传字符串_[转载]Java与C之间通过JNI传递中文字符串

本文详细介绍了如何使用JNI在Java和C之间传递包含中文字符的字符串,提供Java代码和C/C++实现,解决中文乱码问题。通过实验环境配置、源代码解析以及编译步骤,展示了在Windows上Java调用C/C++动态链接库进行跨语言字符串传递的方法。

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

简介

本文提供一个具体的实例,说明Java和C之间通过JNI传递含有中文字符串的参数,解决中文乱码问题(双字节或多字节乱码)。本文给出具体的源代码,对源代码进行了解释,C部分提供了

C和C++两种方式实现的完整代码。并且所有代码均在实验环境下测试通过。本文读者须对Java和C(或C++)有一定的基础知识。

实验环境

Windows XP (或Windows2000)

j2sdk1.4.2/j2re1.4.2

Microsoft

VisualC++6.0

安装好j2sdk后需要设置环境变量

CLASSPATH=.;C:j2sdk1.4.2bin;C:j2sdk1.4.2libdt.jar;C:j2sdk1.4.2libtools.jar;C:j2sdk1.4.2libhtmlconverter.jar(j2sdk安装在c:j2sdk1.4.2目录下)

源代码及代码说明

Java代码:

public class javactransfer

{

public String

hypotenuse(String send_buf,String recv_buf,int errno)

{

return hypotenuse0(send_buf,recv_buf,errno);

}

private native

String

hypotenuse0(String send_buf,String recv_buf,int errno);

static

{

System.loadLibrary("javactransfer");//调用dll

}

public static void

main( String[] args )

{

javactransfer obj= new javactransfer();

System.out.println("");

System.out.println("");

System.out.println("

begin!");

System.out.println("");

System.out.println("");

String javasend="发送中文chinese!";

System.out.println(" java send:"+"["+javasend+"]");

String

javarecv=obj.hypotenuse("teststr",javasend,1);

//javasend传含有中文字符串给C

//javarecv接受C含有中的文字符串

System.out.println(" java recv:"+"["+javarecv+"]");

System.out.println("");

System.out.println("");

System.out.println("

end!");

}

}

C实现代码为:

#include

#include "javactransfer.h"//通过javah –jni javactransfer 生成

#include

#include "stdlib.h"

#include "string.h"

char* jstringToWindows( JNIEnv *env, jstring jstr

);

jstring WindowsTojstring( JNIEnv* env, char* str

);

JNIEXPORT jstring JNICALL

Java_javactransfer_hypotenuse0(JNIEnv *env,jobject

obj,jstring send_buf,jstring recv_buf,jint errno)

{

char *

Buf_Return;

Buf_Return

=

(char*)malloc(1024);

const char * recvtest

= jstringToWindows( env, recv_buf );

printf( " c recv :[%s]n" ,

recvtest);

sprintf(Buf_Return,"接收中文chinese!");

printf( "nnn c

send

:[%s]n" , Buf_Return);

recv_buf =

WindowsTojstring(env ,Buf_Return);

return

recv_buf;

}

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;

}

若javactransfer.java,javactransfer.c均放在d:javac目录下

blog_710177a20102wd9w.html

javac javactransfer.java :编译java源代码;

javah –jni javactransfer :生成头文件;

cl -Ic:j2sdk1.4.2include

-Ic:j2sdk1.4.2includewin32 -LD javactransfer.c

-Fejavactransfer.dll

通过Microsoft Visual

C++将C源代码生成dll文件,供java调用。

执行结果如下:

blog_710177a20102wd9w.html

C++实现代码为:

#include

#include "javactransfer.h"//通过javah –jni javactransfer 生成

#include

#include "stdlib.h"

#include "string.h"

char* jstringToWindows( JNIEnv *env, jstring jstr

);

jstring WindowsTojstring( JNIEnv* env, char* str

);

JNIEXPORT jstring JNICALL

Java_javactransfer_hypotenuse0(JNIEnv *env,jobject

obj,jstring send_buf,jstring recv_buf,jint _tperrno)

{

char *

Buf_Return;

Buf_Return

=

(char*)malloc(1024);

const char * ctest =

jstringToWindows( env, recv_buf );

printf( "

c

recv

:[%s]n" , ctest);

sprintf(Buf_Return,"接收中文chinese!");

printf( "nnn c

send

:[%s]n" , Buf_Return);

recv_buf =

WindowsTojstring(env ,Buf_Return);

return

recv_buf;

}

char* jstringToWindows( 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;

}

jstring WindowsTojstring( JNIEnv* env, char* str

)

{

jstring rtn =

0;

int slen =

strlen(str);

unsigned short *

buffer = 0;

if( slen == 0

)

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

else

{

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

NULL, 0 );

buffer = (unsigned short *)malloc( length*2 + 1 );

if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen,

(LPWSTR)buffer, length ) >0 )

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

length );

}

if( buffer

)

free( buffer

);

return

rtn;

}

当为C++实现时,只需要在编译时改为:

cl -Ic:j2sdk1.4.2include

-Ic:j2sdk1.4.2includewin32 -LD javactransfer.cpp

-Fejavactransfer.dll

后话

本文所述内容可以应用于复杂系统的改造,现有大型生产系统(例如:金融等)很多都是unix+C+tuxedo基于共享内存实现,而这些系统为了满足安全和响应时间要求不可能在短期内完全丢弃,本文中提供的方法,可以和tuxedo客户端通过VC++封装成各种dll,这些dll可以在tuxedo本身很多优良特性的基础上进行基于Java的开发,以用来解决新的基于WEB应用的需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值