Java and C pass through the Chinese string and garbled problems in JNI

xiaoxiao2021-03-06  38

Java and C pass the Chinese string through JNI

Introduction

This article provides a specific example, which shows that JAVA and C pass through the JNI passing parameters containing Chinese strings, solve Chinese garbled problems (double bytes or multi-bytes). This article gives the specific source code, explained the source code, and the C portion provides a complete code implemented by both C and C . And all code is tested in an experimental environment. The readers of this article must have a certain basis of Java and C (or C ).

lab environment

Windows XP (or Windows2000)

J2SDK1.4.2 / J2RE1.4.2

Microsoft Visualc 6.0

Environment variables need to be set after installing J2SDK

Classpath = .; C: /J2SDK1.4.2/bin; c: /j2sdk1.4.2/lib/dt.jar; C: /J2SDK1.4.2/lib/tools.jar; c: /j2sdk1.4.2/lib/htmlconverter. JAR (J2SDK installed in C: /J2SDK1.4.2 directory)

Source code and code description

Java code:

/ *

* JavacTransfer.java

* By DPWU

* E-mail: dpwu_js@sina.com.cn

* /

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"); // Call 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 = "Send Chinese Chinese!";

System.out.println ("Java Send:" "[" Javasend "]");

String Javarecv = Obj.hypotenuse ("Teststr", JavaSend, 1);

// javasend transmits a Chinese string to c

// javarecv Accepts C containing a word string

System.out.println ("Java Recv: " [" Javarecv "] ");

System.out.println ("");

System.out.println ("");

System.out.println ("end!");

}

}

C Implementation code is:

/ *

* JavacTransfer.c

* By DPWU

* E-mail: dpwu_js@sina.com.cn

* /

#include #include "javactransfer.h" // Generate through 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);

/ * The above sentence Recvtest receives the Chinese string of java passed correctly, if it is changed to the next sentence, there is garbled:

Const char * recvtest = (* env) -> GetStringutfchars (ENV, RECV_BUF, 0);

* /

Printf ("C RECV: [% S] / N", Recvtest);

Sprintf (buf_return, "receiving Chinese CHINESE!");

Printf ("/ N / N / N C Send: [% s] / N", buf_return);

RECV_BUF = WindowsTojstring (ENV, BUF_RETURN);

/ * The upper sentence RECV_BUF Biography Windows Local C contains Chinese string to Java correctly; if it is changed to the following sentence, garbled:

RECV_BUF = (* ENV) -> Newstringutf (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 (MultibyToWideChar (CP_ACP, 0, (LPCSTR) STR, SLEN, (LPWSTR) Buffer, Length)> 0)

RTN = (* ENV) -> Newstring (ENV, (JCHAR *) Buffer, Length);

}

IF (buffer)

Free (buffer);

Return RTN;

}

If JavacTransfer.java, JavacTransfer.c is placed in a D: / javac directory

Do the following steps under the command operator:

Javac JavacTransfer.java: Compile Java source code;

Javah-Jni JavacTransfer: Generate header file;

Cl -ic: /j2sdk1.4.2/include -ic: /j2sdk1.4.2/include/win32-ld javacTransfer.c -fejavactransfer.dll

Generate a DLL file by Microsoft Visual C for Java calls.

The result is as follows:

Type: Java JavacTranfer can see the result

C implementation code is:

/ *

* javacTransfer.cpp

* By DPWU

* E-mail: dpwu_js@sina.com.cn

* /

#include

#include "javactransfer.h" // Generate through 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);

/ *

If the above sentence is changed to the next sentence, the C will receive garbled when the Java string is received:

Const char * ctest = (ENV) -> getStringutfchars (Recv_buf, 0);

* /

Printf ("C RECV: [% S] / N", CTEST);

Sprintf (buf_return, "receiving Chinese CHINESE!");

Printf ("/ N / N / N C Send: [% s] / N", buf_return);

RECV_BUF = WindowsTojstring (ENV, BUF_RETURN);

/ * The sentence is executed correctly, if the sentence is changed to the following sentence, Java has garbled when receiving the C string

RECV_BUF = (ENV) -> newstringutf (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 = MultibyToWideChar (CP_ACP, 0, (LPCSTR) STR, SLEN, NULL, 0);

Buffer = (unsigned short *) malloc (length * 2 1);

IF (MultibyToWideChar (CP_ACP, 0, (LPCSTR) STR, SLEN, (LPWSTR) Buffer, Length)> 0)

RTN = (ENV) -> Newstring ((Jchar *) Buffer, Length);

}

IF (buffer)

Free (buffer);

Return RTN;

}

When implementing C , you only need to change it when compiling:

Cl -ic: /j2sdk1.4.2/include -ic: /j2sdk1.4.2/include/win32-ld javacTransfer.cpp -fejavactransfer.dll

Later

The content described herein can be applied to complex systems, and there are many existing large-scale production systems (eg, finance, etc.) are all Unix C Tuxedo is based on shared memory implementation, and these systems are impossible to meet security and response time requirements. Fully discarded, the methods provided herein, can be encapsulated into various DLLs with the Tuxedo client through VC , which can develop Java-based development on the basis of tuxedo itself, to solve new web applications. Demand. If there is any mistake, please contact the author: dpwu_js@sina.com.cn.

Reference: David Wendt "NLS Strings and JNi"

WebSphere Programmer, IBM

转载请注明原文地址:https://www.9cbs.com/read-78250.html

New Post(0)