Need help mapping a struct for platform functions

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

Need help mapping a struct for platform functions

jtuchel
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/2aWUMd-YvKwJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

Seth Berman
Hi Joachim...did you intend '4' to be '2' in the filename:  setter ??

-- Seth

On Tuesday, October 2, 2012 10:05:00 AM UTC-4, [hidden email] wrote:
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/G9diNDghJlAJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

John O'Keefe-3
In reply to this post by jtuchel
Joachim -
 
You need to account for data alignment in the struct. There will be 2 bytes of padding between preview and filename (because 32-bit pointers are 4-byte aligned). So the actual size of the struct is 8, not 6, and filename is at offset 4.

On Tuesday, October 2, 2012 10:05:00 AM UTC-4, [hidden email] wrote:
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/vtlwSJ0LHegJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

jtuchel
In reply to this post by Seth Berman
Hi Seth,

in fact, I wanted it to be 2, but if I understand John's answer correctly, I need to always allow 4 bytes for a pointer, even if it is smaller. So I guess they all should be multiples of 4...
Thanks for taking your time to answer.


Joachim


Am Dienstag, 2. Oktober 2012 18:27:36 UTC+2 schrieb Seth Berman:
Hi Joachim...did you intend '4' to be '2' in the filename:  setter ??

-- Seth

On Tuesday, October 2, 2012 10:05:00 AM UTC-4, [hidden email] wrote:
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/LEkVPUZHSmQJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

jtuchel
In reply to this post by John O'Keefe-3
Hi John,

thanks for this info. So I changed the struct sizes, and I also found some code that helped me get getter and setter to work (as long as I do not make a call).

For setting char * in the struct I use:

self uint32At: 4 put: aString asPSZ copyToOSMemory.

and for reading it back from the structure, I use:

(OSStringZ address: (self uint32At: 4)) asString


Is this the right way to do it?
I guess I have to free these instances of OSStringZ? What if I have really big text parameters (starting at 20K, including a full xml file)? Do I reuse these or free them or simplz not care?


Joachim






Am Dienstag, 2. Oktober 2012 18:58:41 UTC+2 schrieb John O'Keefe:
Joachim -
 
You need to account for data alignment in the struct. There will be 2 bytes of padding between preview and filename (because 32-bit pointers are 4-byte aligned). So the actual size of the struct is 8, not 6, and filename is at offset 4.

On Tuesday, October 2, 2012 10:05:00 AM UTC-4, [hidden email] wrote:
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/v8Q1stiKCaMJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

Normand Mongeau-2
In reply to this post by John O'Keefe-3
But the first member of the struct is defined as unsigned short, not a pointer, so your initial size and offset were good.

Normand

On Tuesday, October 2, 2012 12:58:41 PM UTC-4, John O'Keefe wrote:
Joachim -
 
You need to account for data alignment in the struct. There will be 2 bytes of padding between preview and filename (because 32-bit pointers are 4-byte aligned). So the actual size of the struct is 8, not 6, and filename is at offset 4.

On Tuesday, October 2, 2012 10:05:00 AM UTC-4, [hidden email] wrote:
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/y8ysLBoeRq4J.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

jtuchel
Normand,

at least moving the second entry to offset 4 didn't hurt.
Thanks to the tips on tnis thread, I could make my code run and I am now redy to send long xml strings to the dll and receive lots of error messages from the library :-)

I am still a bit unsure about the freeing question. Should I reuse an instance of OSStringZ with 40K or realllocate a new one for eac call? This function will have to be called several hundreds of times per day on a web server...

Joachim

Am Mittwoch, 3. Oktober 2012 15:02:40 UTC+2 schrieb Normand Mongeau:
But the first member of the struct is defined as unsigned short, not a pointer, so your initial size and offset were good.

Normand

On Tuesday, October 2, 2012 12:58:41 PM UTC-4, John O'Keefe wrote:
Joachim -
 
You need to account for data alignment in the struct. There will be 2 bytes of padding between preview and filename (because 32-bit pointers are 4-byte aligned). So the actual size of the struct is 8, not 6, and filename is at offset 4.

On Tuesday, October 2, 2012 10:05:00 AM UTC-4, [hidden email] wrote:
Hi,

I need to pass a struct to a library function that looks like this:

typedef struct {
 unsigned short preview;
 const char* filename;
} myparameter;

As far as I understand things now, I need to subclass OSStructure. Here's what I have so far:


OSStructure subclass: #MyParameter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''!

!MyParameter class publicMethods !

initializeAfterLoad

    "self initializeAfterLoad"
    self
        fixedSize: 6;
        members: #(#preview #filename).! !

!MyParameter publicMethods !


initialize
    self preview: false.
    self filename: './temp.pdf'.
    !

filename
    ^(self uint32At: 2) asString!

filename: einString
    ^self uint32At: 4 put: einString asPSZ!

preview
    ^(self uint16At: 0) = 1!

preview: aBool
    ^self uint16At: 0 put: (aBool ifTrue: [1] ifFalse: [0])! !

MyParameter initializeAfterLoad!


So far, getting and setting the boolean parameter (preview) seems to work, but I struggle with the String parameter.
So here are my questions:

Are my assumptions correct about the sizes/types: unsigned short = unit16, char * = uint32?
Is the setter for the string (#filename:) correct? I guess the answer is NO, but I don't know what else to do.
When I have to pass this struct to a platform function, do I define the parameter as a #pointer ? (My guess would be YES)
Do I free OSStructure instances after each call?

Thanks for answering

Joachim

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/qsXo8N2hrRkJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

Marten Feldtmann-2
New instance ....

Marten

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

Marten Feldtmann-2
In reply to this post by jtuchel
Hmmmmmm ???

Marten

Am Freitag, 5. Oktober 2012 07:03:54 UTC+2 schrieb [hidden email]:
Normand,

at least moving the second entry to offset 4 didn't hurt.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/0Ens3VNI__8J.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

jtuchel
Hi Marten,

Did I say something stupid (again)?

My current (seemingly running) implementation leaves a gap of two bytes between the Boolean and the String parameters (offsets 0 and 4). So far, doing a few dozen calls did not crash or return any strange results. Do you mean that having these two bytes unused in the middle of the struct is wrong/dangerous/unpredictable/unethical or a bad idea for any other reason?

Joachim

Am Freitag, 5. Oktober 2012 09:56:33 UTC+2 schrieb Marten Feldtmann:
Hmmmmmm ???

Marten

Am Freitag, 5. Oktober 2012 07:03:54 UTC+2 schrieb [hidden email]:
Normand,

at least moving the second entry to offset 4 didn't hurt.

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/5hvPrJJcHH4J.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

Marten Feldtmann-2
It should be (we are working on 32 bit systems):

* on the Smalltalk side I would expect byte offset 0 and 2
* a short is normally 2 bytes aligned
* a pointer is normally 4 bytes aligned

and an offset of 4 is strange (i think its a typing error).

Marten

As a reference what might happens here:

http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Need help mapping a struct for platform functions

Marten Feldtmann-2
Hmm, that was bulshit.

The structure itself is already located with an aligment suitable for the largest member of the structure - here a pointer with a 4 byte alignment.

start of the structure (4 byte aligned)
+0 - short
+1 - short
+2 - local structure alignment padding due to following pointer
+3 - local structure alignment padding due to following pointer
+4 - pointer
+5 - pointer
+6 - pointer
+7 - pointer

Therefore the size of the structure is 8 bytes and the offsets to the data elements are "0" and "4".


Am Freitag, 5. Oktober 2012 12:13:01 UTC+2 schrieb Marten Feldtmann:


* on the Smalltalk side I would expect byte offset 0 and 2

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/va-smalltalk/-/tkhYmcOtO7AJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/va-smalltalk?hl=en.