Understanding NBOpenGL

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

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Igor Stasenko
On 4 June 2013 11:40, kilon <[hidden email]> wrote:

> Ok new problem, NBOpengl seems to not work at all on my UBUNTU 12.10 machine.
> I was trying to do GLViewportMorph new openInWorld , which works fine on my
> iMac and it gave me error: function unavailable.
>
> So I assumed it cannot find some dynamic library , so I checked around the
> code and found that in package NBXLib-Core
> NBXlibHandle>>nbLibraryNameOrHandle class method, it returns
> '/usr/lib/libX11.so'. However browsing through the directories its clear
> that the library is not located in there but rather is located as a symlink
> in a) /usr/lib/i386-linux-gnu b) /usr/lib/x86_64-linux-gnu. Both symlink
> point to libx11.so.6.3.0 libraries.
>
> So knowning that pharo is 32 bit I went for option (a) however still it
> gives me the same error.
>
> Any idea what it may be ?
>
> Another question I have is does it not NB check first to see if the library
> is available ? Because it looks weird that it complains about non existent
> functions but does not complain about non existent library.
>

NB uses a VM API to look for a function in library.
That function provides no error feedback (just success or not).
and also, it combines with loading library as well.
So it is hard to say what exactly happened: did library failed to load or
library loaded fine, but function not found.
(see #loadSymbol:fromModule:  implementation)

To put an end to endless mystery, i propose you to implement a small
diagnostic tool..
There is not much to do:
 - call dlopen()
 - if it fails, call dlerror() , and get details about failure.
 - call dlsym
 - if it fails, call dlerror() , and get details about failure.


> Here is the stack
>
> NBFFICallout(Object)>>error:
> NBFFICallout>>generateCall:module:
> NBGlxAPI>>call: in Block: [...]
> NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry: in Block:
> [...]
> BlockClosure>>on:do:
> NBRecursionDetect class>>in:during:
> NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry:
> NBFFICallout class(NBNativeCodeGen class)>>handleFailureIn:nativeCode:
> NBGlxAPI>>call:
> NBGlxAPI>>queryExtension:errorBase:eventBase:
> NBGLXContextDriver>>createContext:
> NBGLContextDriver class>>createContext:
> NBGLDisplay class>>extent:
> GLViewportMorph>>initializeForNewSession
> GLViewportMorph>>initialize
> GLViewportMorph class(Behavior)>>new
> UndefinedObject>>DoIt
> Compiler>>evaluate:in:to:notifying:ifFail:logged:
> SmalltalkEditor>>evaluateSelectionAndDo:
> SmalltalkEditor>>evaluateSelection
> PluggableTextMorph>>doIt in Block: [...]
> PluggableTextMorph>>handleEdit: in Block: [...]
> TextMorphForEditView(TextMorph)>>handleEdit:
> PluggableTextMorph>>handleEdit:
> PluggableTextMorph>>doIt
> Workspace(Object)>>perform:orSendTo:
> ToggleMenuItemMorph(MenuItemMorph)>>invokeWithEvent: in Block: [...]
> BlockClosure>>ensure:
> CursorWithMask(Cursor)>>showWhile:
> ToggleMenuItemMorph(MenuItemMorph)>>invokeWithEvent:
>
>
>
>
> --
> View this message in context: http://forum.world.st/Understanding-NBOpenGL-tp4686514p4691549.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
Ok I am moving towards the direction you indicated , its just takes time because I am clueless.

Af far as macos is concerned I was sucessful into intialising opengl context following your instructions and using clearColor assigned green-blue background to it. Works like a charm even changing the code updates the window to the corresponding color, live coding in all its glory. I am having tons of fun with it.

I have a strange bug , well it seems that opengl looses a connection with memory and i have to reinitialize my GLTutorial1 class and pops a framebuffer error. It does it only after some time passes and pharo is idle, its a strange bug, but if it starts appearing again I will try to pin point it, because my code is not up to the opengl standards yet so it may be me that cause this issue.

My problem right now is that I follow the tutorial at arcsynth and I am stuck here

http://www.arcsynthesis.org/gltut/Basics/Tut01%20Following%20the%20Data.html

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);

the question is how i find the size in smalltalk . There is bufferData_target:  size:  data:  usage:  which corresponds to that function but I have no idea how to convert sizeof() to smalltalk. Any clues ?

If you want to see my code I have commited it in NBOpengl smalltalkhub the latest is NBOpenGL-Morphic-kilon.10 for NBOpenGL-Morphic.
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Igor Stasenko
On 9 June 2013 20:47, kilon <[hidden email]> wrote:

> Ok I am moving towards the direction you indicated , its just takes time
> because I am clueless.
>
> Af far as macos is concerned I was sucessful into intialising opengl context
> following your instructions and using clearColor assigned green-blue
> background to it. Works like a charm even changing the code updates the
> window to the corresponding color, live coding in all its glory. I am having
> tons of fun with it.
>
> I have a strange bug , well it seems that opengl looses a connection with
> memory and i have to reinitialize my GLTutorial1 class and pops a
> framebuffer error. It does it only after some time passes and pharo is idle,
> its a strange bug, but if it starts appearing again I will try to pin point
> it, because my code is not up to the opengl standards yet so it may be me
> that cause this issue.
>
> My problem right now is that I follow the tutorial at arcsynth and I am
> stuck here
>
> http://www.arcsynthesis.org/gltut/Basics/Tut01%20Following%20the%20Data.html
> <http://www.arcsynthesis.org/gltut/Basics/Tut01%20Following%20the%20Data.html>
>
> glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions,
> GL_STATIC_DRAW);
>
> the question is how i find the size in smalltalk . There is
> bufferData_target:  size:  data:  usage:  which corresponds to that function
> but I have no idea how to convert sizeof() to smalltalk. Any clues ?
>


Yes.

(NBExternalType sizeOf: 'float') * number of floats in your buffer

or

(NBExternalType sizeOf: 'double') * number of floats in your buffer

For arrays of static type, i would recommend you using NBExternalArray,
which gives you a convenient way to deal with arrays of any static
type in smalltalk way.
For passing it as argument to function you can use  'array address' idiom.
See class comments for details.

Btw, getting the size of array, in bytes,  would be:

sizeInBytes
   ^ self size * self class elementSize

(i think this method would be nice to have).

> If you want to see my code I have commited it in NBOpengl smalltalkhub the
> latest is NBOpenGL-Morphic-kilon.10 for NBOpenGL-Morphic.
>
>
>
> --
> View this message in context: http://forum.world.st/Understanding-NBOpenGL-tp4686514p4692494.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Igor Stasenko
On 10 June 2013 03:54, Igor Stasenko <[hidden email]> wrote:

> On 9 June 2013 20:47, kilon <[hidden email]> wrote:
>> Ok I am moving towards the direction you indicated , its just takes time
>> because I am clueless.
>>
>> Af far as macos is concerned I was sucessful into intialising opengl context
>> following your instructions and using clearColor assigned green-blue
>> background to it. Works like a charm even changing the code updates the
>> window to the corresponding color, live coding in all its glory. I am having
>> tons of fun with it.
>>
>> I have a strange bug , well it seems that opengl looses a connection with
>> memory and i have to reinitialize my GLTutorial1 class and pops a
>> framebuffer error. It does it only after some time passes and pharo is idle,
>> its a strange bug, but if it starts appearing again I will try to pin point
>> it, because my code is not up to the opengl standards yet so it may be me
>> that cause this issue.
>>

Sorry, did not replied to this part.
Yes, i found strange behavior as well: it creates context every 2nd time,
and giving error in between.
There could be some wrong code in handling the context..
(it also can be related to GC, because context is not destroyed
directly in my demo,
but released by finalization)

>> My problem right now is that I follow the tutorial at arcsynth and I am
>> stuck here
>>
>> http://www.arcsynthesis.org/gltut/Basics/Tut01%20Following%20the%20Data.html
>> <http://www.arcsynthesis.org/gltut/Basics/Tut01%20Following%20the%20Data.html>
>>
>> glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions,
>> GL_STATIC_DRAW);
>>
>> the question is how i find the size in smalltalk . There is
>> bufferData_target:  size:  data:  usage:  which corresponds to that function
>> but I have no idea how to convert sizeof() to smalltalk. Any clues ?
>>
>
>
> Yes.
>
> (NBExternalType sizeOf: 'float') * number of floats in your buffer
>
> or
>
> (NBExternalType sizeOf: 'double') * number of floats in your buffer
>
> For arrays of static type, i would recommend you using NBExternalArray,
> which gives you a convenient way to deal with arrays of any static
> type in smalltalk way.
> For passing it as argument to function you can use  'array address' idiom.
> See class comments for details.
>
> Btw, getting the size of array, in bytes,  would be:
>
> sizeInBytes
>    ^ self size * self class elementSize
>
> (i think this method would be nice to have).
>
>> If you want to see my code I have commited it in NBOpengl smalltalkhub the
>> latest is NBOpenGL-Morphic-kilon.10 for NBOpenGL-Morphic.
>>
>>
>>
>> --
>> View this message in context: http://forum.world.st/Understanding-NBOpenGL-tp4686514p4692494.html
>> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>>
>
>
>
> --
> Best regards,
> Igor Stasenko.



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
I am trying to find out what version of Opengl NBOpenGL is using so I do:

gl getString:GL_VERSION.

it works and returns me a pointer. I looked at definition of methods and it is defined to return a pointer.

Question is how I get the string that the pointer points too ?
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Guy Hylton
Have you tried

(gl getString: GL_VERSION) readString

or if it does not return an NBExternalAddress

(NBExternalAddress value: (gl getString: GL_VERSION)) readstring




On Sat, Jun 22, 2013 at 4:46 PM, kilon <[hidden email]> wrote:
I am trying to find out what version of Opengl NBOpenGL is using so I do:

gl getString:GL_VERSION.

it works and returns me a pointer. I looked at definition of methods and it
is defined to return a pointer.

Question is how I get the string that the pointer points too ?



--
View this message in context: http://forum.world.st/Understanding-NBOpenGL-tp4686514p4694552.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
No I did not, because I dont have the brain power to assume that NBExternalAdress will have some methods to make my life easier. And of course it works like a charm now, thank you very much :)
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
next question .

I have this method.

initializeProgram
        "create each shader and program"

        | shaderList strVertexShader strFragmentShader |
       
  strVertexShader  := self createShader: GL_VERTEX_SHADER string:  ( self vertexShader ).
        strFragmentShader  := self createShader:  GL_FRAGMENT_SHADER string: (self fragmentShader) .  
        shaderList := #( strVertexShader strFragmentShader ).
        self createProgram:  shaderList .
        shaderList do: [ :each | gl deleteShader: each  ].


Each time I try to accept the code it complains that strVertexShader and strFragmentShader are unused and ask for removing them . Why ?

Is this an IDE bug ? Its clear from the code that I use those two local variables to pass them to the array shaderList. Am I missing something here ?
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Marcus Denker-4

On Jun 23, 2013, at 4:52 PM, kilon <[hidden email]> wrote:

> next question .
>
> I have this method.
>
> initializeProgram
> "create each shader and program"
>
> | shaderList strVertexShader strFragmentShader |
>
> strVertexShader  := self createShader: GL_VERTEX_SHADER string:  ( self
> vertexShader ).
> strFragmentShader  := self createShader:  GL_FRAGMENT_SHADER string: (self
> fragmentShader) .  
> shaderList := #( strVertexShader strFragmentShader ).
> self createProgram:  shaderList .
> shaderList do: [ :each | gl deleteShader: each  ].
>
>
> Each time I try to accept the code it complains that strVertexShader and
> strFragmentShader are unused and ask for removing them . Why ?
>
> Is this an IDE bug ? Its clear from the code that I use those two local
> variables to pass them to the array shaderList. Am I missing something here
> ?

Yes:

shaderList := #( strVertexShader strFragmentShader ).

here the Array you create is a so called literal Array. It can not contain
variables, only literals. The compiler sees is as

        #(#strVertexShader #strFragmentShader).

What you need instead is a compile time evaluated Array:

        shaderList := {strVertexShader strFragmentShader}.

        Marcus
 



Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
yeah and I read about that in PBE and of course I forgot about it. That is why we need the mailing lists.

Ok that solved the problem partially it does not complain about strVertexShader but it still complains about strFragmentShader . I use this code.

 shaderList := {strVertexShader strFragmentShader}.

Any idea what may still be wrong ?

"strFragmentShader appears to be unused in this method. Ok to remove it ?"
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Marcus Denker-4

On Jun 23, 2013, at 5:51 PM, kilon <[hidden email]> wrote:

> yeah and I read about that in PBE and of course I forgot about it. That is
> why we need the mailing lists.
>
> Ok that solved the problem partially it does not complain about
> strVertexShader but it still complains about strFragmentShader . I use this
> code.
>
> shaderList := {strVertexShader strFragmentShader}.
>
> Any idea what may still be wrong ?
>

There needs to be a dot:

shaderList := {strVertexShader . strFragmentShader}.

(I guess I forgot to put it in my example)

> "strFragmentShader appears to be unused in this method. Ok to remove it ?"


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
thank you , it works now.
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
My code

gl shaderSource_shader: shader count: 1  string: shaderString  length: 0.

must not be correct. I try to translate this

glShaderSource(shader, 1, &strFileData, NULL);

using the tutorial in here -> http://www.arcsynthesis.org/gltut/Basics/Tut01%20Making%20Shaders.html

I made these assumptions here

a) Nativeboost would take my string shaderString and pass its address to glShaderSource()
b) that NB would automagically convert 0 to NULL

are these assumptions correct and if yes why I am getting an "error during FFI call: NIL"

if no, how I can pass the address of the string and how may I pass NULL as well ?

as always you can get my code manually from the NBOpengl repo in smalltalk hub to take a look at the whole code. I have not added my code to ConfigurationOfNBOpenGL cause it does not work yet and its a WIP.
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
I also tried

gl shaderSource_shader: shader count: 1  string: (NBExternalAddress fromString: shaderString)  length: (NBExternalObject null) .

still getting "Error during FFI call : NIL" .

This is the full method :

createShader: shaderType string: shaderString
        " create shader using its source and compile it , return shader"

        | shader |
        shader := gl createShader: shaderType .
        gl shaderSource_shader: shader count: 1  string: (NBExternalAddress fromString: shaderString)  length: (NBExternalObject null) .
        gl compileShader: shader.
        ^ shader

. I also use gl getError to get any possible opengl error in my part , It reports that there is no such error.I am continuing investigating Nativeboost
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

kilon
According to the 2.1 reference in opengl website

http://www.opengl.org/sdk/docs/man2/

glShaderSource

I have to pass an array of pointers that point to the strings that make the shader's source. Question is does NBExternalAdress fromString: shaderString , does that ? If no, how I create an array of pointers from a single string ?

It looks like that the call itself fails because nativeboost does not like how I call the function, so that explains why I get no opengl error.
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Igor Stasenko
In reply to this post by kilon
On 27 June 2013 10:30, kilon <[hidden email]> wrote:

> I also tried
>
> gl shaderSource_shader: shader count: 1  string: (NBExternalAddress
> fromString: shaderString)  length: (NBExternalObject null) .
>
> still getting "Error during FFI call : NIL" .
>
> This is the full method :
>
> createShader: shaderType string: shaderString
>         " create shader using its source and compile it , return shader"
>
>         | shader |
>         shader := gl createShader: shaderType .
>         gl shaderSource_shader: shader count: 1  string: (NBExternalAddress
> fromString: shaderString)  length: (NBExternalObject null) .
>         gl compileShader: shader.
>         ^ shader
>

i think it fails because you passing strange (NBExternalObject null)
as length parameter.
i guess you meant  NBExternalAddress null instead.

here the function prototype:

void glShaderSource ( GLuint shader , GLsizei count , GLchar** string
, long* length )

so, length and string is both pointers, and NB marshalling knows only that
(it doesn't knows if there are arrays of strings, ints or whatever).
So, to make it happy you must pass instances of NBExternalAddress as
both of there parameters.

And code will look like:

assume that you have an array of strings, holding the shader sources,
lets call it sources.

sources := #( ' this is first'  'this is second' 'etc' ).

sizeOfPointer := NBExternalType sizeOf: 'void*'.

"allocate buffer for array of pointers"

externalArrayOfPointers := NativeBoost allocate: sizeOfPointer * sources size.

"allocate strings and copy them to external heap"
sourcesOnHeap := sources collect: [:each | NBExternalAddress fromString: each ].

"copy string pointers to external array"
sourcesOnHeap withIndexDo: [:ptr :i |
   "using nbUInt32AtOffset because we know pointer is 4 bytes :) "
    externalArrayOfPointers nbUInt32AtOffset: (i-1)*4 put: ptr value
]

and now you can call that function

 gl shaderSource_shader: shader count:  sources size  string:
externalArrayOfPointers
   length: (NBExternalAddress null) .

but after, don't forget to free the memory:

sourcesOnHeap do: [:each | each free].
externalArrayOfPointers free.


> . I also use gl getError to get any possible opengl error in my part , It
> reports that there is no such error.I am continuing investigating
> Nativeboost
>
>
>
> --
> View this message in context: http://forum.world.st/Understanding-NBOpenGL-tp4686514p4695575.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Henrik Sperre Johansen

On Jun 27, 2013, at 2:22 , Igor Stasenko wrote:

i think it fails because you passing strange (NBExternalObject null)
as length parameter.
i guess you meant  NBExternalAddress null instead.

Speaking of weird external stuff…

NBExternalArray  class >> #initElementType:  aTypeName
"Initialize the element type and size.
If you want to use a public subclass of me, then make sure you call this method
in your class #initialize method.

elementType := aTypeName.
elementSize := (NBFFICallout new requestor: self; resolveType: elementType) valueSize .
self installAccessors.

Shouldn't that be storageSize?
Or is a disclaimer not to use the class for, say, 'char*' elements more appropriate?

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

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Igor Stasenko
On 27 June 2013 15:34, Henrik Johansen <[hidden email]> wrote:

>
> On Jun 27, 2013, at 2:22 , Igor Stasenko wrote:
>
> i think it fails because you passing strange (NBExternalObject null)
> as length parameter.
> i guess you meant  NBExternalAddress null instead.
>
>
> Speaking of weird external stuff…
>
> NBExternalArray  class >> #initElementType:  aTypeName
> "Initialize the element type and size.
> If you want to use a public subclass of me, then make sure you call this
> method
> in your class #initialize method.
> "
>
> elementType := aTypeName.
> elementSize := (NBFFICallout new requestor: self; resolveType: elementType)
> valueSize .
> self installAccessors.
>
> Shouldn't that be storageSize?

Yes, you right.
(NBFFICallout new resolveType: 'byte*') valueSize  => 1
(NBFFICallout new resolveType: 'byte*') storageSize  => 4

apparently, if one wants array with 'byte*' element type (or any other)
it should use a pointer size (4), not byte size (1) for it.

> Or is a disclaimer not to use the class for, say, 'char*' elements more
> appropriate?
>
no , it should be fine.
The difference between valueSize and storageSize is a bit confusing,
and easy to confuse which to use..
Perhaps they need different naming.
There also stackSize, which means "how many bytes a value of given type
will take, if pushed on stack , and aligned accordingly"

... after some more investigation, i found that actually
storageSize should not be used. There is typeSize instead.

So, the final expression should be:

elementType := aTypeName.
elementSize := (NBFFICallout new requestor: self; resolveType:
elementType) typeSize.


and #sizeOf: method should also use typeSize apparently.


> Cheers,
> Henry


--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Henrik Sperre Johansen

On Jun 27, 2013, at 4:11 , Igor Stasenko wrote:

>
>> Or is a disclaimer not to use the class for, say, 'char*' elements more
>> appropriate?
>>
> no , it should be fine.

Was thinking of that in conjunction with putting ST object refs in the External arrays, the trying to pass as parameters, it could be a recipe for disaster :)
Like, say:

"Add a null at end so ExternalArrays basic #readString won't keep on readin'"
string := 'Hello world!' copyWith: (Character value: 0).
extArray := (NBExternalArray ofType: 'char*') new: 1.
"Tenure the string first, lest we invalidate on next scavenge"
Smalltalk garbageCollectMost.
extArray at:1 put: string.

"X our fingers, and hope GC doesn't move string.
Often serves as a nice example that it will :)"
(extArray at: 1) readString  
string at: 7 put: $W.
(extArray at: 1) readString

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

Re: [Pharo-dev] [Pharo-project] Understanding NBOpenGL

Igor Stasenko
On 27 June 2013 17:14, Henrik Johansen <[hidden email]> wrote:

>
> On Jun 27, 2013, at 4:11 , Igor Stasenko wrote:
>
>>
>>> Or is a disclaimer not to use the class for, say, 'char*' elements more
>>> appropriate?
>>>
>> no , it should be fine.
>
> Was thinking of that in conjunction with putting ST object refs in the External arrays, the trying to pass as parameters, it could be a recipe for disaster :)
> Like, say:
>
> "Add a null at end so ExternalArrays basic #readString won't keep on readin'"
> string := 'Hello world!' copyWith: (Character value: 0).
> extArray := (NBExternalArray ofType: 'char*') new: 1.
> "Tenure the string first, lest we invalidate on next scavenge"
> Smalltalk garbageCollectMost.
> extArray at:1 put: string.
>
> "X our fingers, and hope GC doesn't move string.
> Often serves as a nice example that it will :)"
> (extArray at: 1) readString
> string at: 7 put: $W.
> (extArray at: 1) readString
>
hehe.. that certainly a recipe for disaster.

That's why there should be no NBExternalValue>>address  (pointing at Ciprian),
which answers a pointer to oop's first byte, like that given test:

testOutVoidArg
        |x value|
        NBTestExternalValue initialize.
        value := 12345678.
        x := NBTestExternalValue new.

        self outputVoidArg: x address value: value.
       
        self assert: x value = value.

may work.
But actually it will not. And this is **WRONG** in same way as your example.

> Cheers,
> Henry



--
Best regards,
Igor Stasenko.

1234