I made a strucutre like this...
when i pass TestStructure to native,
ValueStructure is not passed witch correct value, setted by java side.
If i change reference method to new Pointer(ValueStructure), I works fine..
What's my mistake?
help me. thank you.
public class ValueStructure extends Structure {
protected Int type = new Int();
protected LongInt ivalue = new LongInt(Long.MIN_VALUE);
protected DoubleFloat dvalue = new DoubleFloat(Double.MIN_VALUE);
protected AnsiString svalue = new AnsiString();
public ValueStructure() {
init(new Parameter[] { type, ivalue, dvalue, new Pointer(svalue)});
}
public Object clone() {
return new ValueStructure(this);
}
...
}
public class TestStructure extends Structure {
public Int index = new Int();
public ValueStructure value = new ValueStructure();
public TestStructure() {
init(new Parameter[] { index, value }); // value is not pointer, new Pointer(value) works fine.
}
public TestStructure(TestStructure self) {
this();
initFrom(self);
}
public Object clone() {
return new TestStructure(this);
}
}
public boolean invoke_testing() {
// extern "C" BOOL PASCAL EXPORT testing(TEST* task)
IntBool result = new IntBool();
TestStructure test = new TestStructure();
test.index.setValue(100);
test.value.setValue(100.0);
native_testing.invoke(result, new Parameter[] { new Pointer(test) });
System.out.println(test.index);
System.out.println(test.value.getDoubleValue());
return result.getBooleanValue();
}
Message was edited by: Philip Choe
Message was edited by: Philip Choe
Hi Philip,
You should use the pointer to a structure, because the native function (// extern "C" BOOL PASCAL EXPORT testing(TEST* task)) expects a pointer.
That's why it worked in second case correctly.
-Serge
I already passed pointer to TestStructure.
My problem is ValueStructure thta elements of TestStrcuture.
TestStructure test = new TestStructure(); native_testing.invoke(result, new Parameter[] { new Pointer(test) }); // extern "C" BOOL PASCAL EXPORT testing(TEST* task) struct _TEST { int index; VALUE value; // not VALUE* value; it's work fine. };
I tried.
case #1
typedef struct _VALUE {
unsigned int type;
long ivalue;
double dvalue;
char* svalue;
} VALUE;
struct _TEST {
unsigned int index;
long dummy; // just a dummy.
VALUE value; // not array. just single Strucut
};
extern "C" BOOL PASCAL EXPORT testing(_TEST* task)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// normal function body here
TRACE("testing called");
TRACE("native: %E\n", task->value.dvalue);
task->index = 500;
task->value.dvalue = -200.0;
return TRUE;
}
public class ValueStructure extends Structure {
protected UInt32 type = new UInt32();
protected LongInt ivalue = new LongInt();
protected DoubleFloat dvalue = new DoubleFloat();
protected AnsiString svalue = new AnsiString();
public ValueStructure() {
init(new Parameter[] { type, ivalue, dvalue, new Pointer(svalue) });
}
}
public class TestStructure extends Structure {
public UInt32 index = new UInt32();
public LongInt dummy = new LongInt();
public ValueStructure value = new ValueStructure(); // not a pointer
public TestStructure() {
init(new Parameter[] { index, dummy, value } );
}
}
public boolean invoke_testing() {
IntBool result = new IntBool();
TestStructure test = new TestStructure();
test.index.setValue(100);
test.value.setValue(100.0);
native_testing.invoke(result, new Parameter[] { new Pointer(test) });
System.out.println(test.index);
System.out.println(test.value.getDoubleValue());
}
case#1 works fine.
500
-200.0
native: 1.00000E+02
case #2. I removed dummy field in TestStructure.
typedef struct _VALUE {
unsigned int type;
long ivalue;
double dvalue;
char* svalue;
} VALUE;
struct _TEST {
unsigned int index;
//long dummy; // removed.
VALUE value; // not array. just single Strucut
};
extern "C" BOOL PASCAL EXPORT testing(_TEST* task)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// normal function body here
TRACE("testing called");
TRACE("native: %E\n", task->value.dvalue);
task->index = 500; // change value
task->value.dvalue = -200.0; // change value
return TRUE;
}
public class TestStructure extends Structure {
public UInt32 index = new UInt32();
//public LongInt dummy = new LongInt();
public ValueStructure value = new ValueStructure(); // not a pointer
public TestStructure() {
init(new Parameter[] { index, /*dummy,*/ value } );
}
}
public class ValueStructure extends Structure {
protected UInt32 type = new UInt32();
protected LongInt ivalue = new LongInt();
protected DoubleFloat dvalue = new DoubleFloat();
protected AnsiString svalue = new AnsiString();
public ValueStructure() {
init(new Parameter[] { type, ivalue, dvalue, new Pointer(svalue) });
}
}
public boolean invoke_testing() {
IntBool result = new IntBool();
TestStructure test = new TestStructure();
test.index.setValue(100);
test.value.setValue(100.0);
native_testing.invoke(result, new Parameter[] { new Pointer(test) });
System.out.println(test.index);
System.out.println(test.value.getDoubleValue());
}
case #2 works wrong.
500
0.0
native: 3.757290E-306 // printed wrong value.
I can't catch a problem whith 2 cases.
What's wrong?
Help me. please.
thank you.
Message was edited by: Philip Choe
Hi Philip,
Thanks for the detailed example. I think that the problem is in the alignment of ValueStructure and TestStructure structures. Please try the following fix:
public static class ValueStructure extends Structure {
protected UInt32 type = new UInt32();
protected LongInt ivalue = new LongInt();
protected DoubleFloat dvalue = new DoubleFloat();
protected AnsiString svalue = new AnsiString();
public ValueStructure() {
init(new Parameter[]{type, ivalue, dvalue, new Pointer(svalue)}, (short) 8);
System.out.println("ValueStructure.length = " + getLength());
}
}
public static class TestStructure extends Structure {
public UInt32 index = new UInt32();
public ValueStructure value = new ValueStructure();
public TestStructure() {
init(new Parameter[]{index, value}, (short) 8);
System.out.println("TestStructure.length = " + getLength());
}
}
As you may notice I have used alignment 8 (default alignment in Visual Studio) instead of the platform-dependent alignment, which is equal to 2 on Windows platforms. In case if value 8 is not suitable, please try another one.
Actually the length of the wrapper (you can get it using .getLength() function) should be equal to the size of the corresponding native structure, which you can check using sizeof(VALUE) macros.
-Serge