我正在尝试使用posix_memalign从java.io.Reader读取到在C中分配的char缓冲区。
在我的java代码中
public class LowerCaseTokenizer
{
public native void Initialize(Reader input) throws IOException;
public static String example = "XY&Z Corporation - xyz@example.com";
public LowerCaseTokenizer(Reader input) throws IOException {
Initialize(input);
}
public static void main(String[] args) throws IOException {
System.loadLibrary("LowerCaseTokenizer");
LowerCaseTokenizer sample = new LowerCaseTokenizer(new StringReader(example));}
}
对于C ++代码,我做了以下内容。
JNIEXPORT void JNICALL Java_LowerCaseTokenizer_Initialize(JNIEnv *env, jobject obj1, jobject obj2){
jclass input_class = env->GetObjectClass(obj2);
jmethodID jread_method = env->GetMethodID(input_class, "read", "(C[II)I" );
print_object_class_name(env, obj2);
}
问题是我得到了
Calling class is: java.io.StringReader // print_object_class_name(env, obj2);
Exception in thread "main" java.lang.NoSuchMethodError: read
获取此方法的目的是我想从读取器读取用C ++分配的缓冲区(我在分配缓冲区时考虑到每个字符问题的UTF16(16位))。
由于这个错误,我没有检查读取缓冲区实现是否会起作用。但是一些见解不会受到伤害。
do{
numCharsRead = env->CallIntMethod(obj2, jread_method ,source_ptr ,off , len);
}while(numCharsRead != -1);
答案 0 :(得分:2)
java.lang.NoSuchMethodError
表示Java无法找到名称和签名与您请求的匹配的方法。您的要求是:
env->GetMethodID(input_class, "read", "(C[II)I" );
您可以使用javap
获取正确的类型签名> javap -s -classpath rt.jar java/io/StringReader
...
public int read(char[], int, int) throws java.io.IOException;
Signature: ([CII)I
但您使用的是(C[II)I
而不是([CII)I
---您的[
错位。
答案 1 :(得分:0)
读取功能的签名不是“(C [II] I”)。
我用c写的不是cpp。但我认为你只需要替换read方法的签名。/*
* Class: com_neohope_jni_test_LowerCaseTokenizer
* Method: Initialize
* Signature: (Ljava/io/Reader;)V
*/
JNIEXPORT void JNICALL Java_com_neohope_jni_test_LowerCaseTokenizer_Initialize
(JNIEnv *env, jobject caller, jobject reader)
{
getJniClassName(env, caller);
getJniClassName(env, reader);
jclass clazz = (*env)->GetObjectClass(env, reader);
if (clazz == NULL)return;
jmethodID midRead01 = (*env)->GetMethodID(env, clazz, "read", "()I");
jmethodID midRead02 = (*env)->GetMethodID(env, clazz, "read", "([C)I");
jmethodID midRead03 = (*env)->GetMethodID(env, clazz, "read", "([CII)I");
//do your job here
if (midRead01 == NULL)return;
jint ret = (*env)->CallIntMethod(env, reader, midRead01);
printf("%l", ret);
}