jniステップテスト
6054 ワード
環境:win 7 64,vs 2008,eclipse 3.7, jdk1.6
JAvaコードは次のとおりです.
cppコードは以下の通りです.
出力:helloオープンソース中国550 1 2 2 3 3 4 helloオープンソース中国1 helloオープンソース中国2 helloオープンソース中国3
参照先:http://yaojingguo.iteye.com/blog/542383
参照先:http://www.linuxidc.com/Linux/2012-05/60870.htm
参照先:http://stackoverflow.com/questions/6504544/passing-array-of-strings-from-c-file-to-java-dll-via-jni/6506390#6506390
JAvaコードは次のとおりです.
package cyper.jni;
public class Test {
public native int sumArray(int[] arr);
public native String getString();
public native String[] getStringArray();
public static native int[][] initInt2DArray(int size);
public static void main(String[] args) {
Test t = new Test();
// String
System.out.println(t.getString());
// int
int arr[] = new int[]{1,2,3,4,5,6,7,8,9,10};
System.out.println(t.sumArray(arr));
//
int[][] i2arr = initInt2DArray(3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(" " + i2arr[i][j]);
}
}
System.out.println();
// String
String[] str = t.getStringArray();
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
static {
System.loadLibrary("test");
}
}
cppコードは以下の通りです.
#include "cyper_jni_Test.h"
#include <windows.h>
#include <vector>
/*
* Class: cyper_jni_Test
* Method: sumArray
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_cyper_jni_Test_sumArray
(JNIEnv * env, jobject obj, jintArray arr)
{
//version 1
/*
jint buf[10];
jint i, sum = 0;
env->GetIntArrayRegion(arr,0,10,buf);
for (i=0;i<10;i++)
{
sum += buf[i];
}
return sum;
*/
//version 2
jint * carr;
jint i, len, sum = 0;
carr = env->GetIntArrayElements(arr,NULL);
if(carr==NULL)
{
return 0;
}
len = env->GetArrayLength(arr);
for (i=0;i<len;i++)
{
sum += carr[i];
}
env->ReleaseIntArrayElements(arr,carr,NULL);
return sum;
}
/*
* Class: cyper_jni_Test
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cyper_jni_Test_getString
(JNIEnv * env, jobject obj){
//version 1
/*
const wchar_t* str = L"Here is a quite long and useless string. Note that this even works with non-ASCII characters, like in ";
size_t len = wcslen(str);
if (sizeof(wchar_t) != sizeof(jchar)) {
printf("this is linux
");
// In Linux, we get there.
// First, allocate a buffer for the string to pass to Java, not forgetting the \0
jchar* str2 = (jchar*)malloc((len+1)*sizeof(jchar));
int i;
for (i = 0; i < len; i++)
// This discards two bytes in str[i], but these should be 0 in UTF-16
str2[i] = str[i];
str2[len] = 0;
// Now we have a compatible string!
jstring js = env->NewString(str2, len);
// And we can free the buffer, to prevent memory leaks
free(str2);
return js;
}
else
{
printf("this is windows
");
// Under Windows, we don't need such a hack
return env->NewString((const jchar *)str, len);
}*/
//version 2
std::wstring wstr(L"hello ");
//NewString unicode jchar *, wstring wchar_t *
const wchar_t * pwchar = const_cast<wchar_t*>(wstr.c_str());
return env->NewString((const jchar *)pwchar,wcslen(pwchar));
}
/*
* Class: cyper_jni_Test
* Method: initInt2DArray
* Signature: (I)[[I
*/
JNIEXPORT jobjectArray JNICALL Java_cyper_jni_Test_initInt2DArray
(JNIEnv * env, jclass cls, jint size)
{
jobjectArray result;
int i;
jclass intArrCls = env->FindClass("[I");
if(intArrCls == NULL)
{
return NULL;
}
result = env->NewObjectArray(size,intArrCls,NULL);
if (result == NULL)
{
return NULL;
}
for (i=0; i<size; i++)
{
jint tmp[256]; //make sure it is large enough,Cyper:I think the same with size is enough!
int j;
jintArray iarr = env->NewIntArray(size);
if(iarr == NULL){
return NULL;
}
for (j=0; j<size; j++)
{
tmp[j] = i+j;
}
env->SetIntArrayRegion(iarr,0,size,tmp);
env->SetObjectArrayElement(result,i,iarr);
env->DeleteLocalRef(iarr);
}
return result;
}
/*
* Class: cyper_jni_Test
* Method: getStringArray
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_cyper_jni_Test_getStringArray
(JNIEnv * env, jobject obj){
const wchar_t* str1 = L"hello 1";
const wchar_t* str2 = L"hello 2";
const wchar_t* str3 = L"hello 3";
std::vector<const wchar_t*> v;
v.push_back(str1);
v.push_back(str2);
v.push_back(str3);
// String
jclass strCls = env->FindClass("java/lang/String");
if(strCls == NULL)
{
return NULL;
}
// 3 String
jobjectArray result = env->NewObjectArray(3,strCls,NULL);
if (result == NULL)
{
return NULL;
}
//
for (int i=0; i<v.size();i++)
{
jobject jstr = env->NewString((const jchar *)v[i],wcslen(v[i]));
env->SetObjectArrayElement(result,i,jstr);
}
return result;
}
出力:helloオープンソース中国550 1 2 2 3 3 4 helloオープンソース中国1 helloオープンソース中国2 helloオープンソース中国3
参照先:http://yaojingguo.iteye.com/blog/542383
参照先:http://www.linuxidc.com/Linux/2012-05/60870.htm
参照先:http://stackoverflow.com/questions/6504544/passing-array-of-strings-from-c-file-to-java-dll-via-jni/6506390#6506390