[Glass] CPointer and a question

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

[Glass] CPointer and a question

marten
Assuming the following code:

I would like to have a pointer to a 4 bytes long area:


CPointer newFrom: (CByteArray gcMalloc: 4)

but this does now work. It must be at least an 8 bytes long field:

CPointer newFrom: (CByteArray gcMalloc: 8)


Why ? Or do I not understand the semantic of newFrom: ? The name
indicates, that the content of the CByteArray is used.

But the description says:

"Return a new instance of CPointer which is a reference to body
 of a CByteArray."


Marten
(Ubuntu 14.04LTS, Gemstone/S 3.2)

--
Marten Feldtmann
_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass
Reply | Threaded
Open this post in threaded view
|

Re: [Glass] CPointer and a question

James Foster-9
Marten,

"An instance of CByteArray encapsulates allocation of C memory or a reference to C memory.” (from the class comment)

"A CPointer encapsulates a C pointer which does not have auto-free semantics.” (from the class comment)

When translating a C world to a Smalltalk world it is best to think of a Smalltalk “object" as a C “pointer.” Therefore, an instance of CByteArray is a pointer (object) to a chunk of C memory (of unspecified use) and an instance of CPointer is a pointer (object) to a 64-bit chunk of memory to be used as a pointer (C).

If you call a C function that returns an address (e.g., malloc), then you would have a CPointer—not a CByteArray. To convert an address (CPointer) to a CByteArray you would need to know the length, and a pointer does not have this information. If you know the length then you can use CByteArray class>>#’fromCPointer:numBytes:’ to convert it to a CByteArray.

If you have a C function that takes a pointer as an argument then you can pass it a CByteArray rather than a pointer. The VM is smart enough to recognize that a function prototype that wants a pointer should be treated as a pass-by-reference rather than a pass-by-value when given a CByteArray. On the other hand, if you give it a CPointer as the argument then it will do a pass-by-value.

When you use CPointer class>>#’newFrom:’ you are telling the VM to use the first 64-bits of the CByteArray as an address.

In general, the only use of a CPointer is as a return value from a function and you should convert it to a CByteArray as soon as you know the length. Otherwise, there should be little need for a CPointer.

For a nice example of using these FFI classes see ExternalSession and GciLibrary in 3.2.0.

James

On Jun 3, 2014, at 6:34 AM, [hidden email] wrote:

> Assuming the following code:
>
> I would like to have a pointer to a 4 bytes long area:
>
>
> CPointer newFrom: (CByteArray gcMalloc: 4)
>
> but this does now work. It must be at least an 8 bytes long field:
>
> CPointer newFrom: (CByteArray gcMalloc: 8)
>
>
> Why ? Or do I not understand the semantic of newFrom: ? The name
> indicates, that the content of the CByteArray is used.
>
> But the description says:
>
> "Return a new instance of CPointer which is a reference to body
> of a CByteArray."
>
>
> Marten
> (Ubuntu 14.04LTS, Gemstone/S 3.2)
>
> --
> Marten Feldtmann
> _______________________________________________
> Glass mailing list
> [hidden email]
> http://lists.gemtalksystems.com/mailman/listinfo/glass

_______________________________________________
Glass mailing list
[hidden email]
http://lists.gemtalksystems.com/mailman/listinfo/glass