JNA结构ByReference

时间:2014-07-11 11:47:50

标签: java jna

以下方法和该方法的单元测试。 问题是我无法从Load方法返回结果的值。 下面的单元测试失败了!

我认为默认情况下JNA的对象默认为ByRef所以我尝试实例化并传递LoadResults"没有" .ByReference ...

我的错误在哪里?

@Test
public void testLoad () {
   MY_Processor proc = new MY_Processor();
   // LoadResults result = new LoadResults ();
   LoadResults.ByReference result = new LoadResults.ByReference();
   ByteByReference [] pathToFile = new ByteByReference[256];
   // fill pathToFile out ... 

   try {
      proc.Load (pathToFile, result);
      assertEquals(0, result.errorCode);
      assertEquals(1, result.elaborationTime);
      assertEquals(2, result.coreItem);
   } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}



public Integer Load ( ByteByReference[] pathToFile, 
                          LoadResults.ByReference result ) throws Exception {

   // here result is correctly filled out !
   LoadResults result = null;
   result = native.getResult (numCore);
}

添加了原生代码。

更新

// header
typedef struct
{
   int     errorCode;
   int     elaborationTime;
   int     coreItem;
} LoadResults;

//[in]  path
//[out] result
int Load (char path[MY_BUFFER_DEFINE], LoadResults* result);
// implementation ...

LoadResults* getResult (int numCore)
{
   // some check ... 

   LoadResults *localResult = new LoadResults();
   // fill out ... 

   return localResult;
}

有一个"免费"本机代码暴露的方法,但我没有显示,以便将注意力集中在我的问题上: - )

/ UPDATE

谢谢!

0

2 个答案:

答案 0 :(得分:0)

问题在于您将Structure作为参数传递,然后在函数中重新分配该参数。这对论证没有任何影响。

您需要遵循的模式是:

Pointer p = mylib.getResult()
MyStructure m = new MyStructure(p);
// ....
mylib.free(p);

我建议您传入原生字符串(const char*)作为路径,而不是原生char的固定大小缓冲区。

<强>更新

如果要将结果复制到参数中,则需要复制结构的内容,例如

public int Load(LoadResults arg) throws Exception {
    // Effectively copy memory from result into arg
    LoadResults result = native.getResult(numCore);
    if (alternative_1) {
        // Copy result's native memory into arg's memory, then sync Java fields
        result.useMemory(arg.getPointer());
        result.write();
        arg.read();
    }
    else {
        // Sync result's native memory with arg's Java fields
        Pointer p = arg.getPointer();
        arg.useMemory(result.getPointer());
        arg.read();
        arg.useMemory(p);
    }
}

答案 1 :(得分:0)

刚刚解决了......

1)我不需要使用LoadResults.ByReference

2)问题在于,在Load方法中,我更新了输入中传递的另一个引用:

public Integer Load ( ByteByReference[] pathToFile, LoadResults result ) throws Exception     
{
   // that's the problem!!!! storing the value into another object with another "address"
   // and not the original "results".
   // result = native.getResult (numCore);

   // solved with this:
   native.getResult (numCore, result);
}