5 messages in net.java.dev.jna.users[jna-users] Nested Structure elements...
FromSent OnAttachments
Michael WhiteJul 25, 2008 2:45 am 
Timothy WallJul 25, 2008 9:49 am 
Michael WhiteJul 25, 2008 10:26 am 
Michael WhiteJul 26, 2008 12:31 am 
Timothy WallJul 27, 2008 8:09 pm 
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:[jna-users] Nested Structure elements arriving uninitialized.Actions...
From:Michael White (sfcl@yahoo.com)
Date:Jul 25, 2008 2:45:33 am
List:net.java.dev.jna.users

Hi,

Despite numerous permutations, I cannot get my nested Structure to work.

I can get the Structure passed through to the Visual C++ DLL running on Windows
XP sp2, but all the array items (i.e. nested Structure elements) are always
uninitialized, even though the Java side clearly shows all the fields as having
been set before the DLL call.

Any help would be greatly appreciated. As it is, I'm stopped dead in my tracks.

Here's the C++ code:

... #ifdef _USRDLL #define PLUGINAPI extern "C" __declspec(dllexport) #else #define PLUGINAPI extern "C" __declspec(dllimport) #endif ...

struct OptimizeItem { char *Name; float Default; float Min; float Max; float Step; double Current; float Best; };

#define MAX_OPTIMIZE_ITEMS 100

struct OptimizeParams { int Mode; int WalkForwardMode; int Engine; int Qty; int LastQty; BOOL CanContinue; BOOL DuplicateCheck; int Reserved; char *InfoText; int InfoTextSize; __int64 Step; __int64 NumSteps; double TargetCurrent; double TargetBest; int TargetBestStep; struct OptimizeItem Items[ MAX_OPTIMIZE_ITEMS ]; };

PLUGINAPI int OptimizerInit( struct OptimizeParams *pParams ); ...

Here's what I've got in Java (the last incarnation I tried anyway). Note:
GenericPlugin extends StdCallLibrary.

public interface OptimizerPlugin extends GenericPlugin { static final int MAX_OPTIMIZE_ITEMS = 100; ... int OptimizerInit(OptimizeParams pParams); ... public static class OptimizeParams extends Structure { public int Mode; public int WalkForwardMode; public int Engine; public int Qty; public int LastQty; public int CanContinue; public int DuplicateCheck; public int Reserved; public byte[] InfoText; public int InfoTextSize; public long Step; public long NumSteps; public double TargetCurrent; public double TargetBest; public int TargetBestStep; public OptimizeItem[] Items = new OptimizeItem[MAX_OPTIMIZE_ITEMS];

public OptimizeParams(String infoText) { InfoText = infoText.getBytes(); InfoTextSize = InfoText.length; allocateMemory(); } }

public static class OptimizeItem extends Structure { public byte[] Name; public float Default; public float Min; public float Max; public float Step; public double Current; public float Best;

public OptimizeItem() { this("x"); }

public OptimizeItem(String name) { Name = name.getBytes(); allocateMemory(); } } ... }

My usage class looks like this (again, my latest try of many many variations)...

final OptimizerPlugin lib = (OptimizerPlugin) Native.loadLibrary("CMAE",
OptimizerPlugin.class); OptimizerPlugin.OptimizeItem[] items = new OptimizerPlugin.OptimizeItem[2];

items[0] = new OptimizerPlugin.OptimizeItem("fast"); items[0].Default = 5.0f; items[0].Min = 1.0f; items[0].Max = 5.0f; items[0].Step = 1.0f; items[0].Current = 0.0d; items[0].Best = 0.0f;

items[1] = new OptimizerPlugin.OptimizeItem("slow"); items[1].Default = 100.0f; items[1].Min = 100.0f; items[1].Max = 200.0f; items[1].Step = 10.0f; items[1].Current = 0.0d; items[1].Best = 0.0f;

final OptimizerPlugin.OptimizeParams pParams = new
OptimizerPlugin.OptimizeParams("Testing");

pParams.Mode = 2; pParams.WalkForwardMode = 1; pParams.Engine = 0; pParams.Qty = 2; pParams.LastQty = 0; pParams.CanContinue = 1; pParams.DuplicateCheck = 1; pParams.Reserved = 0; pParams.Step = 0L; pParams.NumSteps = 0L; pParams.TargetCurrent = 0.0d; pParams.TargetBest = 0.0d; pParams.TargetBestStep = 0; pParams.Items[0] = items[0]; pParams.Items[1] = items[1];

System.out.println(pParams.toString()); int result = lib.OptimizerInit(pParams); ...

Here's the toString() result

OptimizerPlugin$OptimizeParams(allocated@0xb078738 (4088 bytes)) { int Mode@0=2 int WalkForwardMode@4=1 int Engine@8=0 int Qty@c=2 int LastQty@10=0 int CanContinue@14=1 int DuplicateCheck@18=1 int Reserved@1c=0 byte InfoText[7]@20=[B@1bd7848 int InfoTextSize@28=7 long Step@30=0 long NumSteps@38=0 double TargetCurrent@40=0.0 double TargetBest@48=0.0 int TargetBestStep@50=0 OptimizerPlugin$OptimizeItem
Items[100]@58=[Lproject1.OptimizerPlugin$OptimizeItem;@23e5d1 }

I also tried using a Pointer, instead of OptimizeItem array, and then passing in
items[0].getPointer() as had been suggested in an earlier thread. But that
didn't work either.

Thanks in advance for any help.