如何在C中获取作业的值?
我使用$(function() {
$('input[type=checkbox]').change(function() {
if (this.checked) {
$(this).closest('tr').find('input[type=text]').prop('disabled', true);
} else {
$(this).closest('tr').find('input[type=text]').prop('disabled', false);
}
});
});
并在C中调用java函数。参数是一个jobject,它看起来应该是这样的:JNI
。
现在我想从该对象获取值,但我不知道如何。你对如何解决这个问题有什么建议吗?
我在C中的结构看起来像是我在java中的类。
我的代码看起来像这样:
{"John", "Ganso", 5}
答案 0 :(得分:5)
/* PassObject.java */
package recipeNo020;
public class PassObject {
/* This is the native method we want to call */
public static native void displayObject(Object obj);
/* Inside static block we will load shared library */
static {
System.loadLibrary("PassObject");
}
public static void main(String[] args) {
/* This message will help you determine whether
LD_LIBRARY_PATH is correctly set
*/
System.out.println("library: "
+ System.getProperty("java.library.path"));
/* Create object to pass */
CustomClass cc = new CustomClass();
cc.iVal = 1;
cc.dVal = 1.1;
cc.cVal = 'a';
cc.bVal = true;
cc.sVal = "Hello from the CustomClass";
cc.oVal = new OtherClass();
cc.oVal.sVal = "Hello from the OtherClass";
/* Call to shared library */
PassObject.displayObject(cc);
}
}
/* CustomClass.java */
package recipeNo020;
public class CustomClass {
public int iVal;
public double dVal;
public char cVal;
public boolean bVal;
public OtherClass oVal;
public String sVal;
}
/* OtherClass.java */
package recipeNo020;
public class OtherClass {
public String sVal;
}
/* recipeNo020_PassObject.c */
#include <stdio.h>
#include "jni.h"
#include "recipeNo020_PassObject.h"
JNIEXPORT void JNICALL Java_recipeNo020_PassObject_displayObject
(JNIEnv *env, jclass obj, jobject objarg) {
/* Get objarg's class - objarg is the one we pass from
Java */
jclass cls = (*env)->GetObjectClass(env, objarg);
/* For accessing primitive types from class use
following field descriptors
+---+---------+
| Z | boolean |
| B | byte |
| C | char |
| S | short |
| I | int |
| J | long |
| F | float |
| D | double |
+-------------+
*/
/* Get int field
Take a look here, we are passing char* with
field descriptor - e.g. "I" => int
*/
jfieldID fidInt = (*env)->GetFieldID(env, cls, "iVal", "I");
jint iVal = (*env)->GetIntField(env, objarg, fidInt);
printf("iVal: %d\n", iVal);
/* Get double field */
jfieldID fidDouble = (*env)->GetFieldID(env, cls, "dVal", "D");
jdouble dVal = (*env)->GetIntField(env, objarg, fidDouble);
printf("dVal: %f\n", dVal);
/* Get boolean field */
jfieldID fidBoolean = (*env)->GetFieldID(env, cls, "bVal", "Z");
jboolean bVal = (*env)->GetIntField(env, objarg, fidBoolean);
printf("bVal: %d\n", bVal);
/* Get character field */
jfieldID fidChar = (*env)->GetFieldID(env, cls, "cVal", "C");
jboolean cVal = (*env)->GetIntField(env, objarg, fidChar);
printf("cVal: %c\n", cVal);
/* Get String field */
jfieldID fidString = (*env)->GetFieldID(env, cls, "sVal", "Ljava/lang/String;");
jobject sVal = (*env)->GetObjectField(env, objarg, fidString);
// we have to get string bytes into C string
const char *c_str;
c_str = (*env)->GetStringUTFChars(env, sVal, NULL);
if(c_str == NULL) {
return;
}
printf("sVal: %s\n", c_str);
// after using it, remember to release the memory
(*env)->ReleaseStringUTFChars(env, sVal, c_str);
/* Get OtherClass */
jfieldID fidOtherClass = (*env)->GetFieldID(env, cls, "oVal", "LrecipeNo020/OtherClass;");
jobject oVal = (*env)->GetObjectField(env, objarg, fidOtherClass);
jclass clsOtherClass = (*env)->GetObjectClass(env, oVal);
/* Once we have OtherClass class and OtherClass object
we can access OtherClass'es components
*/
/* Get String field from OtherClass */
jfieldID fidStringOtherClass = (*env)->GetFieldID(env, clsOtherClass, "sVal", "Ljava/lang/String;");
jobject sValOtherClass = (*env)->GetObjectField(env, oVal, fidStringOtherClass);
// we have to get string bytes into C string
const char *c_str_oc;
c_str_oc = (*env)->GetStringUTFChars(env, sValOtherClass, NULL);
if(c_str_oc == NULL) {
return;
}
printf("OtherClass.sVal: %s\n", c_str_oc);
// after using it, remember to release the memory
(*env)->ReleaseStringUTFChars(env, sValOtherClass, c_str_oc);
}
/* Make file */
include ../Makefile.common
all: compilejava compilec
compilec:
cc -g -shared -fpic -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(ARCH) c/recipeNo020_PassObject.c -o lib/libPassObject.$(EXT)
compilejava:
$(JAVA_HOME)/bin/javac -cp target -d target java/recipeNo020/OtherClass.java
$(JAVA_HOME)/bin/javac -cp target -d target java/recipeNo020/CustomClass.java
$(JAVA_HOME)/bin/javac -cp target -d target java/recipeNo020/PassObject.java
$(JAVA_HOME)/bin/javah -jni -d c -cp target recipeNo020.PassObject
test:
$(JAVA_HOME)/bin/java -Djava.library.path=$(LD_LIBRARY_PATH):./lib -cp target recipeNo020.PassObject
.PHONY: clean
clean:
-rm -rfv target/*
-rm c/recipeNo020_PassObject.h
-rm -rfv lib/*
/* directory structure */
.
├── Makefile
├── c
│ └── recipeNo020_PassObject.c
├── java
│ └── recipeNo020
│ ├── CustomClass.java
│ ├── OtherClass.java
│ └── PassObject.java
├── lib
└── target
/* execution */
make
make test
您可以更轻松地签出项目并进行编译:
答案 1 :(得分:2)
无论您是编写本机方法还是在C程序中嵌入JVM,您都应该阅读the JNI documentation。它包含了您需要了解的大量信息,包括the JNI functions for accessing the fields of a Java object的详细信息。
简而言之,要获得字段的值,
通过db.getCollection('mycollection').eval(function construct(){
var res = db.getCollection('mycollection').find(query);
var explain = res.explain()['server'];
return {'server':explain,'result':res.toArray()};
})()
获取其字段ID。这将要求您获得(或已经拥有)表示该字段所属类的{
"server" : "myservernode.mydomain:27017",
"result" : [
// your query results
]
}
对象;您可以通过GetFieldID()
或jclass
使用GetObjectClass()
方法之一获取字段的值,FindClass()
适合字段的声明类型。对于Java GetXXXField()
,那将是XXX
;对于Java String
,它将是GetObjectField()
。
如果您想查看字符串的详细信息,还需要使用String manipulation functions中的一些内容,例如int
和GetIntField()
。并且不要忽视那些以修改后的UTF-8运行的功能与以“Unicode字符”(实际上意味着UTF-16)运行的类似功能之间的重要区别。
答案 2 :(得分:0)
我同意John Bollinger的观点。 以下是基于另一个[问题]的示例:JNI. How to get jstring from jobject and convert it to char*
在您的情况下,如果java中的类是Person,并且字段是firstName,lastName和age,那么您可以尝试以下代码:
// How can I get values of jobject o?
jclass personClass = (*env)->GetObjectClass(env, o);
jfieldID firstNameId = (*env)->GetFieldID(env,personClass,"firstName","S");
jstring firstNameString = (jstring)(*env)->GetObjectField(env, o, firstNameId);
jfieldID lastNameId = (*env)->GetFieldID(env,personClass,"lastName","S");
jstring lastNameString = (jstring)(*env)->GetObjectField(env, o, lastNameId);
jfieldID ageId = (*env)->GetFieldID(env,personClass,"age","I");
jint age = (*env)->GetIntField(env,o,ageId);
现在您可以使用该数据填充您的结构。