4 messages in net.java.dev.jna.usersRe: [jna-users] Fields getting clobbe...
FromSent OnAttachments
Michael WhiteSep 14, 2008 4:02 pm 
Timothy WallSep 14, 2008 5:39 pm 
Michael WhiteSep 15, 2008 2:18 am 
Timothy WallSep 15, 2008 3:08 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] Fields getting clobbered between callsActions...
From:Timothy Wall (twal@dev.java.net)
Date:Sep 14, 2008 5:39:55 pm
List:net.java.dev.jna.users

On Sep 14, 2008, at 7:02 PM, Michael White wrote:

Hi,

Could someone please have a look at the following code and offer suggestions as to how to correct it?

Thanks in advance.

1. I am instantiating an instance of my structure in java. I also instantiate an instance of my Callback in java, passing a wrapper of my structure instance as constructor argument.

2. I then loop passing the structure instance as an argument to native C++ call. The loop terminates based on a calculation derived from the Step field of my structure.

3. The native C++ uses the structure for its own initizliations then calls back into my java Callback (does not pass the structure to the Callback, I cannot alter that API, which is why I passed the structure to the Callback at the time of its own construction).

4. Inside the java callback, I am incrementing the Step field of my structure and returning. The expectation is that the loop in (2.) above will eventually terminate as Step increases.

The problem that I am having is that the changes made to my structure from within the Callback (4.) are no longer present when the looping logic goes to check for the termination condition (2.). I end up with an infinate loop.

Unless you invoke Structure.write or Structure.writeField before your callback returns, the Java field values will not be written to native memory. Normally write/read is called automatically across a function call, but in this case you have to do the update explicitly since there's no way for JNA to guess that it needs to be done.

Here's the looping logic: (My structure is an instance of OptimizeParams as constructed and held by Optimization. GridBacktesterImpl is my Callback implementation)

... Optimization optimization = null;

try { final OptimizerPlugin lib = (OptimizerPlugin) Native.loadLibrary(name, OptimizerPlugin.class);

optimization = new Optimization(descriptor); ... OptimizeParams params = optimization.getOptimizeParams(); GridBacktesterImpl fitness = new GridBacktesterImpl(optimization); ... do { lib.OptimizerRun(params, fitness, null); run = (params.Step < params.NumSteps); ... } while (run); } catch (Exception x) { ... }

Here are the declarations in my Optimization object (I tried with and without the volatile keyword. Did not seem to make any difference):

public class Optimization ... { private volatile OptimizeParams params;

public Optimization(OptimizationDescriptor descriptor) { ... params = new OptimizeParams(); params.Step = 0;

}

public OptimizeParams getOptimizeParams() { return params; } ... }

Here is my Callback implementation (interface GridBacktester extends Callback):

private final class GridBacktesterImpl implements GridBacktester { private Optimization optimization;

GridBacktesterImpl(Optimization optimization) { this.optimization = optimization; }

public double callback(Pointer ptr) { OptimizeParams params = optimization.getOptimizeParams(); int sets = ...;

for (int i = 0; i < sets; i++) { ... params.Step++;

// sync to native memory params.write(); // or params.writeField("Step");

Here is my structure declaration. I tried with and without the volatile keyword (did not appear to have any effect):

Volatile means that JNA will *not* automatically update the field, that you must do so explicitly. That won't help you in this case.