2

我必须通过一个结构

   struct Info {
    u_int8_t timestamp[8];
    u_int32_t  a;
    u_int32_t  b;
    u_int32_t  c;
    ActiveInfo activeInfo[MAX_ACTIVE_SET];

   };

 struct ActiveInfo
{
   u_int8_t  is_reference;
   u_int16_t p;
   u_int32_t q;
    u_int8_t  r;
   u_int8_t  s;
  };
  typedef struct ActiveInfo ActiveInfo;

我想将此(信息)结构传递给我的 java 代码。我已经目瞪口呆,但没有得到完整的方法来做到这一点。

谢谢。

4

3 回答 3

4

该结构必须在 Java 端定义为具有成员的类。事实上,JNI 允许 C 访问 Java 对象,但不允许 Java 访问 C 对象(结构)。因此,如果您想通过 JNI “传递”某些内容并使其在双方都可访问,则它必须是 Java 对象,然后jobject在接口中进行限定。从 C 方面来看,您有两个选择:

  • 要么直接使用GetFieldID()and访问成员Get/Set<Type>Field,尽管使用数组更复杂(我看到了一些)
  • 或在该类中创建 Java 方法以简化方式填充和读取,并调用它们Invoke<Retval>Method

这取决于您的数据存储设计。您可能只希望一侧(C 或 Java)读取而另一侧写入,这可以方便地反映在设计中。

编辑:

可以在@asgoth 指出的站点找到示例:www.steveolyo.com。有一章名为“将 C 结构从 C 传递到 Java”,但随后它默默地解释了如何在 Java 类中反映所需的 C 结构并通过 JNI 将 Java 对象传递给 C——这正是我的回复所说的。

于 2012-12-21T13:04:23.257 回答
2

你需要一个 JNIEXPORT:

JNIEXPORT jint JNICALL 
Java_FillCStruct
(
   JNIEnv *env, 
   jclass obj, 
   jobject    info      // EntryInformation object instantiation
)
{
   testInfo entryInfo;
   jclass clazz;
   jfieldID fid;
   jmethodID mid;

   GetInfo(entryInfo);   // fills in the entryInfo

   clazz = (*env)->GetObjectClass(env, info);
   if (0 == clazz)
   {
      printf("GetObjectClass returned 0\n");
      return(-1);
   }
   fid = (*env)->GetFieldID(env,clazz,"index","I");

   // This next line is where the power is hidden. Directly change
   // even private fields within java objects. Nasty!
   (*env)->SetIntField(env,info,fid,testInfo.index); 
...

这是一个带有一些示例的站点:http: //www.steveolyo.com/JNI/JNI.html

于 2012-12-21T10:47:01.747 回答
1

您已经知道映射仅以一种方式起作用:您可以从 C/C++ 访问 Java 类,反之则不行。

但同样重要的是要记住,这种映射涉及大量开销——无论是在使用的内存中还是在 CPU 中。

因此,放弃完全透明可能是明智之举。例如,如果你只需要读取activeInfo[n].s,你可以写一个native方法getais(int n)。或者 uou 可以将 java 中的整个结构作为 DirectByteBuffer 接收,计算所需的偏移量,并直接操作该值。

于 2012-12-21T19:05:48.243 回答