我有一个以用户定义的数据类型(结构)作为参数的本机方法。如何使用 JNI 从 java 调用此方法?
问问题
1945 次
2 回答
2
如果你有这样的方法:
int cFunction(mydatatype data) ...
你不能直接调用它。您将需要一层 JNI 将其粘合在一起。
因此,您的代码会生成一个 JNI 函数:
class JavaTest {
public native int jMethod(int a);
}
在那个类上运行javah
你会得到一个像这样的头文件:
JNIEXPORT jint JNICALL Java_Javatest_jMethod(JNIEnv*, jobject obj, jint a);
实现该方法来调用cFunction(mydatatype)
:
JNIEXPORT jint JNICALL Java_Javatest_jMethod(JNIEnv*, jobject obj, jint a) {
mydatatype data;
data.count = a;
return (jint) cFunction(data);
}
于 2012-05-29T08:46:38.863 回答
2
有办法读取 java 对象字段:
jint _JMETHODNAME(MyClass,myMethod) (JNIEnv *env, jclass jcMyClass, jobject joMyObject)
{
//Get the class
jcMyObjectClass = env->FindClass("test/native/MyObject");
if (jtException = env->ExceptionOccurred())
{
//Error management
}
if (jcMyObjectClass == NULL)
{
//Error management
}
//Check if the class matchs the object
jboolean jbFlag = env->IsInstanceOf(joMyObject,jcMyObjectClass);
if (jtException = env->ExceptionOccurred())
{
//Error management
}
if (jbFlag == JNI_FALSE)
{
//Error management
}
//Get a field
jfieldID jfIdentField = env->GetFieldID(jcMyObjectClass,"fieldName","Ljava/lang/String;");
if (jtException = env->ExceptionOccurred())
{
//Error management
}
if (jfIdentField == NULL)
{
//Error management
}
//Read a field
jstring jsMyString = (jstring)env->GetObjectField(joMyObject,jfIdentField);
if (jtException = env->ExceptionOccurred())
{
//Error management
}
if (jsMyString == NULL)
{
//Error management
}
//Convert to C++ format
LPCTSTR strMyString = (LPTSTR)env->_tGetString(jsMyString, NULL);
jsize myStringLen = env->_tGetStringLength(jsMyString);
if (strMyString == NULL)
{
//Error management
}
}
因此,您可以使用 Java 对象作为参数,并根据需要将其转换为 C 结构。
也许这对你有帮助。
对于自引用对象,您可以像这样遍历所有对象:
//Get a field
jfieldID jfIdentField = env->GetFieldID(jcMyObjectClass,"selfReference","test/native/MyObject");
if (jtException = env->ExceptionOccurred())
{
//Error management
}
if (jfIdentField == NULL)
{
//Error management
}
//Read a field
jobject joNextMyObject = (jstring)env->GetObjectField(joMyObject,jfIdentField);
if (jtException = env->ExceptionOccurred())
{
//Error management
}
while (joNextMyObject != NULL)
{
//Process object
//Read a field
joNextMyObject = (jstring)env->GetObjectField(joNextMyObject,jfIdentField);
if (jtException = env->ExceptionOccurred())
{
//Error management
}
}
于 2012-05-29T09:53:41.400 回答