[UFFI] Using a nested structure

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

[UFFI] Using a nested structure

MerwanOuddane

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan
Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

Ronie Salgado
Hi Merwan,

I tested this on Pharo 6 and it is working in Windows. However, in 32 bits Window doubles have an 8 byte alignment, unlike Linux where they have a 4 byte alignment.

Can you try doing the following before performing the ffi call in Windows, if you are moving an image from Linux or OS X:

Vec3 rebuildFieldAccessors.
Position rebuildFieldAccessors.

Best regards,
Ronie

2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan

Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
I am not moving from another plateform :/

I tried it in pharo 6 and I it didn't work either.

It could be my dll. What is your compilation line for the dll ?

Thanks you,
Merwan

On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]> wrote:
Hi Merwan,

I tested this on Pharo 6 and it is working in Windows. However, in 32 bits Window doubles have an 8 byte alignment, unlike Linux where they have a 4 byte alignment.

Can you try doing the following before performing the ffi call in Windows, if you are moving an image from Linux or OS X:

Vec3 rebuildFieldAccessors.
Position rebuildFieldAccessors.

Best regards,
Ronie

2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan


Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
Using codeblocks, mine are:

mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o bin\Release\Test.dll -s -m32


On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]> wrote:
I am not moving from another plateform :/

I tried it in pharo 6 and I it didn't work either.

It could be my dll. What is your compilation line for the dll ?

Thanks you,
Merwan

On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]> wrote:
Hi Merwan,

I tested this on Pharo 6 and it is working in Windows. However, in 32 bits Window doubles have an 8 byte alignment, unlike Linux where they have a 4 byte alignment.

Can you try doing the following before performing the ffi call in Windows, if you are moving an image from Linux or OS X:

Vec3 rebuildFieldAccessors.
Position rebuildFieldAccessors.

Best regards,
Ronie

2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan



Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

Ronie Salgado
I compiled the DLL using Visual Studio 2015 Community Edition. Later I will check with mingw.

2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
Using codeblocks, mine are:

mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o bin\Release\Test.dll -s -m32


On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]> wrote:
I am not moving from another plateform :/

I tried it in pharo 6 and I it didn't work either.

It could be my dll. What is your compilation line for the dll ?

Thanks you,
Merwan

On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]> wrote:
Hi Merwan,

I tested this on Pharo 6 and it is working in Windows. However, in 32 bits Window doubles have an 8 byte alignment, unlike Linux where they have a 4 byte alignment.

Can you try doing the following before performing the ffi call in Windows, if you are moving an image from Linux or OS X:

Vec3 rebuildFieldAccessors.
Position rebuildFieldAccessors.

Best regards,
Ronie

2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan




Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
Another test:
I replaced double by integer, for visibility...
typedef struct vec3 {
     int data[3];
} vec3;

add a second vec3 to position:

typedef struct position {
     int i;
     vec3 vec;
     vec3 vec2;
} position;

Now in pharo:
Position >> fieldsDesc
"self rebuildFieldAccessors"
    ^ #(
    int i;
    Vec3 vec;
    Vec3 vec2;
)

The size returned for each stucture is 16 instead of 12 that because of the "8 byte alignment"

Meaning that the "position" structure is corrupted.

With this function:


extern "C" void DLL_EXPORT fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
    (position -> vec2).data[0] = 1;
    (position -> vec2).data[1] = 2;
    (position -> vec2).data[2] = 3;
}

We will get:
position i == 19
position vec at: 1 == 1
position vec2 at: 1 == 2


On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
I compiled the DLL using Visual Studio 2015 Community Edition. Later I will check with mingw.

2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
Using codeblocks, mine are:

mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o bin\Release\Test.dll -s -m32


On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]> wrote:
I am not moving from another plateform :/

I tried it in pharo 6 and I it didn't work either.

It could be my dll. What is your compilation line for the dll ?

Thanks you,
Merwan

On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]> wrote:
Hi Merwan,

I tested this on Pharo 6 and it is working in Windows. However, in 32 bits Window doubles have an 8 byte alignment, unlike Linux where they have a 4 byte alignment.

Can you try doing the following before performing the ffi call in Windows, if you are moving an image from Linux or OS X:

Vec3 rebuildFieldAccessors.
Position rebuildFieldAccessors.

Best regards,
Ronie

2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan





Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
PS: for the first example, the alignment is not respected, the vec3 structure is starting at 9 but uffi is fetching it at 5

On 06/07/2016 17:55, Merwan Ouddane wrote:
Another test:
I replaced double by integer, for visibility...
typedef struct vec3 {
     int data[3];
} vec3;

add a second vec3 to position:

typedef struct position {
     int i;
     vec3 vec;
     vec3 vec2;
} position;

Now in pharo:
Position >> fieldsDesc
"self rebuildFieldAccessors"
    ^ #(
    int i;
    Vec3 vec;
    Vec3 vec2;
)

The size returned for each stucture is 16 instead of 12 that because of the "8 byte alignment"

Meaning that the "position" structure is corrupted.

With this function:


extern "C" void DLL_EXPORT fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
    (position -> vec2).data[0] = 1;
    (position -> vec2).data[1] = 2;
    (position -> vec2).data[2] = 3;
}

We will get:
position i == 19
position vec at: 1 == 1
position vec2 at: 1 == 2


On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
I compiled the DLL using Visual Studio 2015 Community Edition. Later I will check with mingw.

2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
Using codeblocks, mine are:

mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o bin\Release\Test.dll -s -m32


On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]> wrote:
I am not moving from another plateform :/

I tried it in pharo 6 and I it didn't work either.

It could be my dll. What is your compilation line for the dll ?

Thanks you,
Merwan

On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]> wrote:
Hi Merwan,

I tested this on Pharo 6 and it is working in Windows. However, in 32 bits Window doubles have an 8 byte alignment, unlike Linux where they have a 4 byte alignment.

Can you try doing the following before performing the ffi call in Windows, if you are moving an image from Linux or OS X:

Vec3 rebuildFieldAccessors.
Position rebuildFieldAccessors.

Best regards,
Ronie

2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:

Hi,

I have an issue whith nested structures.

I made some "dummy" structures in c:


typedef struct vec3 {
     double data[3];
} vec3;

typedef struct position {
     int i;
     vec3 vec;
} position;

And a "dummy" function to fill it:
void fillStruct(position *position)
{
    position -> i = 19;
    (position -> vec).data[0] = 1;
    (position -> vec).data[1] = 2;
    (position -> vec).data[2] = 3;
}

But I can't make the nested structure work.
The "i" is correctly set to 19 but I have values that doesn't make any sense in the vec3 structure.

In Pharo
I declared the Double3 type for the array inside Vec3:
Double3 := FFITypeArray ofType: 'double' size: 3

Vec3>>fieldsDesc
    ^ #(
    Double3 v;
)

And the position:
Position>>fieldsDesc
    ^ #(
    int i;
    Vec3 vec;
)

The ffi call:
^ self ffiCall: #(void fillStruct(Position *position)) module: 'Test.dll'

Sorry for the long / messy mail :p

Any clues ?

Cheers,
Merwan






Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

Ben Coman
On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
> PS: for the first example, the alignment is not respected, the vec3
> structure is starting at 9 but uffi is fetching it at 5

Hi Esteban,

Is it possible to get a feature or a recipe to output the sizeof or
offset of fields in types as understood by the Image, and the same
from a C side - that could be used as the standard first step in
troubleshooting these kinds of issues ?

cheers -ben

>
>
> On 06/07/2016 17:55, Merwan Ouddane wrote:
>
> Another test:
> I replaced double by integer, for visibility...
> typedef struct vec3 {
>      int data[3];
> } vec3;
>
> add a second vec3 to position:
>
> typedef struct position {
>      int i;
>      vec3 vec;
>      vec3 vec2;
> } position;
>
> Now in pharo:
> Position >> fieldsDesc
> "self rebuildFieldAccessors"
>     ^ #(
>     int i;
>     Vec3 vec;
>     Vec3 vec2;
> )
>
> The size returned for each stucture is 16 instead of 12 that because of the
> "8 byte alignment"
>
> Meaning that the "position" structure is corrupted.
>
> With this function:
>
>
> extern "C" void DLL_EXPORT fillStruct(position *position)
> {
>     position -> i = 19;
>     (position -> vec).data[0] = 1;
>     (position -> vec).data[1] = 2;
>     (position -> vec).data[2] = 3;
>     (position -> vec2).data[0] = 1;
>     (position -> vec2).data[1] = 2;
>     (position -> vec2).data[2] = 3;
> }
>
> We will get:
> position i == 19
> position vec at: 1 == 1
> position vec2 at: 1 == 2
>
>
> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>
>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>> will check with mingw.
>>
>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>
>>> Using codeblocks, mine are:
>>>
>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>> bin\Release\Test.dll -s -m32
>>>
>>>
>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>> wrote:
>>>>
>>>> I am not moving from another plateform :/
>>>>
>>>> I tried it in pharo 6 and I it didn't work either.
>>>>
>>>> It could be my dll. What is your compilation line for the dll ?
>>>>
>>>> Thanks you,
>>>> Merwan
>>>>
>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>> wrote:
>>>>>
>>>>> Hi Merwan,
>>>>>
>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>> 4 byte alignment.
>>>>>
>>>>> Can you try doing the following before performing the ffi call in
>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>
>>>>> Vec3 rebuildFieldAccessors.
>>>>> Position rebuildFieldAccessors.
>>>>>
>>>>> Best regards,
>>>>> Ronie
>>>>>
>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I have an issue whith nested structures.
>>>>>>
>>>>>> I made some "dummy" structures in c:
>>>>>>
>>>>>>
>>>>>> typedef struct vec3 {
>>>>>>      double data[3];
>>>>>> } vec3;
>>>>>>
>>>>>> typedef struct position {
>>>>>>      int i;
>>>>>>      vec3 vec;
>>>>>> } position;
>>>>>>
>>>>>> And a "dummy" function to fill it:
>>>>>> void fillStruct(position *position)
>>>>>> {
>>>>>>     position -> i = 19;
>>>>>>     (position -> vec).data[0] = 1;
>>>>>>     (position -> vec).data[1] = 2;
>>>>>>     (position -> vec).data[2] = 3;
>>>>>> }
>>>>>>
>>>>>> But I can't make the nested structure work.
>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>> sense in the vec3 structure.
>>>>>>
>>>>>> In Pharo
>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>
>>>>>> Vec3>>fieldsDesc
>>>>>>     ^ #(
>>>>>>     Double3 v;
>>>>>> )
>>>>>>
>>>>>> And the position:
>>>>>> Position>>fieldsDesc
>>>>>>     ^ #(
>>>>>>     int i;
>>>>>>     Vec3 vec;
>>>>>> )
>>>>>>
>>>>>> The ffi call:
>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>> 'Test.dll'
>>>>>>
>>>>>> Sorry for the long / messy mail :p
>>>>>>
>>>>>> Any clues ?
>>>>>>
>>>>>> Cheers,
>>>>>> Merwan
>>>>>
>>>>>
>>>>
>>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

EstebanLM
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?
FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3
 
(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>


Position.st (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>



Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>



Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

EstebanLM
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>




Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>





Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

EstebanLM
that still does not helps… show me the code!

Esteban

On 08 Jul 2016, at 20:09, Merwan Ouddane <[hidden email]> wrote:

Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>






Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
Struct >> fieldsDesc
    ^#( void* a;
    Enum b;
    Enum c;
    )

Enum >> enumDecl
    ^ #( TEST 1 )

I joined a .st with the struct and the enum, the package name is FFITest.

Merwan

On 08/07/2016 20:14, Esteban Lorenzano wrote:
that still does not helps… show me the code!

Esteban

On 08 Jul 2016, at 20:09, Merwan Ouddane <[hidden email]> wrote:

Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>








FFITest.st (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

EstebanLM
it works fine for me: 

Struct>>b
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 5)

Struct>>b: anObject
"This method was automatically generated"
handle unsignedLongAt: 5 put: anObject value

Struct>>c
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 9)

Struct>>c: anObject
"This method was automatically generated"
handle unsignedLongAt: 9 put: anObject value

question: did you initialise the Enum? before generating fields?

Esteban

On 08 Jul 2016, at 20:42, Merwan Ouddane <[hidden email]> wrote:

Struct >> fieldsDesc
    ^#( void* a;
    Enum b;
    Enum c;
    )

Enum >> enumDecl
    ^ #( TEST 1 )

I joined a .st with the struct and the enum, the package name is FFITest.

Merwan

On 08/07/2016 20:14, Esteban Lorenzano wrote:
that still does not helps… show me the code!

Esteban

On 08 Jul 2016, at 20:09, Merwan Ouddane <[hidden email]> wrote:

Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>







<FFITest.st>

Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

MerwanOuddane
Yes I did.

Have you tried on windows ?

Merwan

On 08/07/2016 21:20, Esteban Lorenzano wrote:
it works fine for me: 

Struct>>b
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 5)

Struct>>b: anObject
"This method was automatically generated"
handle unsignedLongAt: 5 put: anObject value

Struct>>c
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 9)

Struct>>c: anObject
"This method was automatically generated"
handle unsignedLongAt: 9 put: anObject value

question: did you initialise the Enum? before generating fields?

Esteban

On 08 Jul 2016, at 20:42, Merwan Ouddane <[hidden email]> wrote:

Struct >> fieldsDesc
    ^#( void* a;
    Enum b;
    Enum c;
    )

Enum >> enumDecl
    ^ #( TEST 1 )

I joined a .st with the struct and the enum, the package name is FFITest.

Merwan

On 08/07/2016 20:14, Esteban Lorenzano wrote:
that still does not helps… show me the code!

Esteban

On 08 Jul 2016, at 20:09, Merwan Ouddane <[hidden email]> wrote:

Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>







<FFITest.st>


Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

Henrik Sperre Johansen
The alignment calculation of external enums is wrong, it should be

FFIExternalEnumerationType >> externalTypeAlignment
^ self representationType externalTypeAlignment

It only manifests for 32bit platforms on Windows  since that's the only one with a pointer alignment (which superclass FFIExternalReferenceType returns) of 8, not 4 (which is the same alignment as the correct FFIUInt alignment)

Cheers,
Henry


On 09 Jul 2016, at 12:08 , Merwan Ouddane <[hidden email]> wrote:

Yes I did.

Have you tried on windows ?

Merwan

On 08/07/2016 21:20, Esteban Lorenzano wrote:
it works fine for me: 

Struct>>b
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 5)

Struct>>b: anObject
"This method was automatically generated"
handle unsignedLongAt: 5 put: anObject value

Struct>>c
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 9)

Struct>>c: anObject
"This method was automatically generated"
handle unsignedLongAt: 9 put: anObject value

question: did you initialise the Enum? before generating fields?

Esteban

On 08 Jul 2016, at 20:42, Merwan Ouddane <[hidden email]> wrote:

Struct >> fieldsDesc
    ^#( void* a;
    Enum b;
    Enum c;
    )

Enum >> enumDecl
    ^ #( TEST 1 )

I joined a .st with the struct and the enum, the package name is FFITest.

Merwan

On 08/07/2016 20:14, Esteban Lorenzano wrote:
that still does not helps… show me the code!

Esteban

On 08 Jul 2016, at 20:09, Merwan Ouddane <[hidden email]> wrote:

Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>







<FFITest.st>




signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Using a nested structure

EstebanLM
Hi,

I uploaded the fix for it. 
it will be integrated soon. 

Esteban

On 11 Jul 2016, at 13:13, Henrik Johansen <[hidden email]> wrote:

The alignment calculation of external enums is wrong, it should be

FFIExternalEnumerationType >> externalTypeAlignment
^ self representationType externalTypeAlignment

It only manifests for 32bit platforms on Windows  since that's the only one with a pointer alignment (which superclass FFIExternalReferenceType returns) of 8, not 4 (which is the same alignment as the correct FFIUInt alignment)

Cheers,
Henry


On 09 Jul 2016, at 12:08 , Merwan Ouddane <[hidden email]> wrote:

Yes I did.

Have you tried on windows ?

Merwan

On 08/07/2016 21:20, Esteban Lorenzano wrote:
it works fine for me: 

Struct>>b
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 5)

Struct>>b: anObject
"This method was automatically generated"
handle unsignedLongAt: 5 put: anObject value

Struct>>c
"This method was automatically generated"
^Enum fromInteger: (handle unsignedLongAt: 9)

Struct>>c: anObject
"This method was automatically generated"
handle unsignedLongAt: 9 put: anObject value

question: did you initialise the Enum? before generating fields?

Esteban

On 08 Jul 2016, at 20:42, Merwan Ouddane <[hidden email]> wrote:

Struct >> fieldsDesc
    ^#( void* a;
    Enum b;
    Enum c;
    )

Enum >> enumDecl
    ^ #( TEST 1 )

I joined a .st with the struct and the enum, the package name is FFITest.

Merwan

On 08/07/2016 20:14, Esteban Lorenzano wrote:
that still does not helps… show me the code!

Esteban

On 08 Jul 2016, at 20:09, Merwan Ouddane <[hidden email]> wrote:

Sorry not unsigned longs but enumerations

On Fri, Jul 8, 2016 at 10:09 AM, Esteban Lorenzano <[hidden email]> wrote:
how do you declare this?

On 08 Jul 2016, at 10:01, Merwan Ouddane <[hidden email]> wrote:

I spoke too fast ^^'

struct Test {
  void * ptr;
  insigned long i;
  insigned long j;
}

Real size is 12, UFFI counts 24

Merwan


Le 7 juil. 2016 10:02, "Merwan Ouddane" <[hidden email]> a écrit :
Now it is working, thank you :)

On Thu, Jul 7, 2016 at 8:42 AM, Esteban Lorenzano <[hidden email]> wrote:
Hi,

> On 07 Jul 2016, at 01:54, Ben Coman <[hidden email]> wrote:
>
> On Thu, Jul 7, 2016 at 12:58 AM, Merwan Ouddane <[hidden email]> wrote:
>> PS: for the first example, the alignment is not respected, the vec3
>> structure is starting at 9 but uffi is fetching it at 5
>
> Hi Esteban,
>
> Is it possible to get a feature or a recipe to output the sizeof or
> offset of fields in types as understood by the Image, and the same
> from a C side - that could be used as the standard first step in
> troubleshooting these kinds of issues ?

FFIExternalType class>>sizeOf: ?

but that does not works for complex type sizes (like FFIExternalArray).

I don’t know what the problem is here, because in my test (attached) it seems to be working fine.
maybe problem is on how the Vec3 array is created, it should be something like this:

Vec3 class>>iinitialize
        self
                type: (FFIExternalType resolveType: 'double')
                size: 3

(is like that because FFITypeArray is more designed to be used creating anonymous types than concretes, but well… )

in any case, it seems to be working for me.

Now, about the use…

doing this:

p := Position new.
p v1 at: 1 put: 42.0.
p v1 at: 1. “will print 0.0"

why? because it works making a copy (maybe it should work passing a segment, as nested structs work, but this is how it works now).

What should work (at doesn’t) in this case is this:

v := Vector3 new.
p := Position new.
v at: 1 put: 42.0.
p v1: v.
p v1 at: 1. “will print 42.0"

it does not work because I made a mistake in field generation that I already fixed… so you will need to update UFFI (and regenerate field accessors) ;)

also… I will provide a fix to make first case work… just later because now I’m going to my french lessons :)

Esteban

ps: for future reference, a description of: install this, run that, is a lot easier to understand the problem (is a case of “show me the code!”) :P




>
> cheers -ben
>
>>
>>
>> On 06/07/2016 17:55, Merwan Ouddane wrote:
>>
>> Another test:
>> I replaced double by integer, for visibility...
>> typedef struct vec3 {
>>     int data[3];
>> } vec3;
>>
>> add a second vec3 to position:
>>
>> typedef struct position {
>>     int i;
>>     vec3 vec;
>>     vec3 vec2;
>> } position;
>>
>> Now in pharo:
>> Position >> fieldsDesc
>> "self rebuildFieldAccessors"
>>    ^ #(
>>    int i;
>>    Vec3 vec;
>>    Vec3 vec2;
>> )
>>
>> The size returned for each stucture is 16 instead of 12 that because of the
>> "8 byte alignment"
>>
>> Meaning that the "position" structure is corrupted.
>>
>> With this function:
>>
>>
>> extern "C" void DLL_EXPORT fillStruct(position *position)
>> {
>>    position -> i = 19;
>>    (position -> vec).data[0] = 1;
>>    (position -> vec).data[1] = 2;
>>    (position -> vec).data[2] = 3;
>>    (position -> vec2).data[0] = 1;
>>    (position -> vec2).data[1] = 2;
>>    (position -> vec2).data[2] = 3;
>> }
>>
>> We will get:
>> position i == 19
>> position vec at: 1 == 1
>> position vec2 at: 1 == 2
>>
>>
>> On Tue, Jul 5, 2016 at 3:12 PM, Ronie Salgado <[hidden email]> wrote:
>>>
>>> I compiled the DLL using Visual Studio 2015 Community Edition. Later I
>>> will check with mingw.
>>>
>>> 2016-07-05 14:58 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>
>>>> Using codeblocks, mine are:
>>>>
>>>> mingw32-g++.exe -m32 -DBUILD_DLL -c main.cpp -o obj\Release\main.o
>>>> mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libTest.def
>>>> -Wl,--out-implib=bin\Release\libTest.a -Wl,--dll  obj\Release\main.o  -o
>>>> bin\Release\Test.dll -s -m32
>>>>
>>>>
>>>> On Tue, Jul 5, 2016 at 2:52 PM, Merwan Ouddane <[hidden email]>
>>>> wrote:
>>>>>
>>>>> I am not moving from another plateform :/
>>>>>
>>>>> I tried it in pharo 6 and I it didn't work either.
>>>>>
>>>>> It could be my dll. What is your compilation line for the dll ?
>>>>>
>>>>> Thanks you,
>>>>> Merwan
>>>>>
>>>>> On Tue, Jul 5, 2016 at 2:14 PM, Ronie Salgado <[hidden email]>
>>>>> wrote:
>>>>>>
>>>>>> Hi Merwan,
>>>>>>
>>>>>> I tested this on Pharo 6 and it is working in Windows. However, in 32
>>>>>> bits Window doubles have an 8 byte alignment, unlike Linux where they have a
>>>>>> 4 byte alignment.
>>>>>>
>>>>>> Can you try doing the following before performing the ffi call in
>>>>>> Windows, if you are moving an image from Linux or OS X:
>>>>>>
>>>>>> Vec3 rebuildFieldAccessors.
>>>>>> Position rebuildFieldAccessors.
>>>>>>
>>>>>> Best regards,
>>>>>> Ronie
>>>>>>
>>>>>> 2016-07-05 11:11 GMT+02:00 Merwan Ouddane <[hidden email]>:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I have an issue whith nested structures.
>>>>>>>
>>>>>>> I made some "dummy" structures in c:
>>>>>>>
>>>>>>>
>>>>>>> typedef struct vec3 {
>>>>>>>     double data[3];
>>>>>>> } vec3;
>>>>>>>
>>>>>>> typedef struct position {
>>>>>>>     int i;
>>>>>>>     vec3 vec;
>>>>>>> } position;
>>>>>>>
>>>>>>> And a "dummy" function to fill it:
>>>>>>> void fillStruct(position *position)
>>>>>>> {
>>>>>>>    position -> i = 19;
>>>>>>>    (position -> vec).data[0] = 1;
>>>>>>>    (position -> vec).data[1] = 2;
>>>>>>>    (position -> vec).data[2] = 3;
>>>>>>> }
>>>>>>>
>>>>>>> But I can't make the nested structure work.
>>>>>>> The "i" is correctly set to 19 but I have values that doesn't make any
>>>>>>> sense in the vec3 structure.
>>>>>>>
>>>>>>> In Pharo
>>>>>>> I declared the Double3 type for the array inside Vec3:
>>>>>>> Double3 := FFITypeArray ofType: 'double' size: 3
>>>>>>>
>>>>>>> Vec3>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    Double3 v;
>>>>>>> )
>>>>>>>
>>>>>>> And the position:
>>>>>>> Position>>fieldsDesc
>>>>>>>    ^ #(
>>>>>>>    int i;
>>>>>>>    Vec3 vec;
>>>>>>> )
>>>>>>>
>>>>>>> The ffi call:
>>>>>>> ^ self ffiCall: #(void fillStruct(Position *position)) module:
>>>>>>> 'Test.dll'
>>>>>>>
>>>>>>> Sorry for the long / messy mail :p
>>>>>>>
>>>>>>> Any clues ?
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Merwan
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>







<FFITest.st>