On Thu, May 7, 2015 at 8:53 AM, Holger Freyther hol...@freyther.de wrote:
Good Morning,
I used NB to access openlog, closelog and syslog of libc and I am not sure
if I got it right but didn’t really get further by browsing
testcases/reading the
examples.
openlog(3) takes an “char *ident” as first parameter and the caller needs
to
make sure that the string passed remains valid until closelog is called.
My binding looks like this:
c_openlog: ident opt: aOpt facility: aFac
openlog(const char *ident, int logopt, int facility);
primitive: #primitiveNativeCall module: #NativeBoostPlugin error:
errorCode
^self nbCall: #(void openlog(char *ident, int aOpt, int aFac))
And I call it like this:
Identity := anIdentity asNBExternalString.
self c_openlog: Identity opt: anOption facility: aFacility.
The things I am not sure with:
1.) is it right to use “char *ident” instead of “String ident”? “String”
will copy
the string by value but the pointer passed to openlog would be a pointer
from
the C callstack?
asNBExternalString will do this with a NBExternalAddress:
fromString: aString
| result |
result := NativeBoost allocate: aString size + 1.
(self assert: result notNil).
result writeString: aString.
^ result
writeString: aString
write a null-terminated byte string to receiver's address
| str |
str := aString copyWith: (Character value: 0).
NativeBoost memCopy: str asByteArray to: self size: str size.
So, yes, it allocates heap memory
basicAllocate: numBytes
Allocate a memory block with given size in bytes,
answer an NBExternalAddress instance - address to the beginning of memory
block
| addr |
addr := heap allocate: numBytes.
addr = 0 ifTrue: [ ^ nil ].
^ NBExternalAddress value: addr
char * looks a null terminated string, which str := aString copyWith:
(Character value: 0). provides
So, asNBExternalString is compatible with the char *
2.) Am I right with the call to asNBExternalString?
Should work.
3.) How does this integrate with GC and image quit/image resume? E.g. I
could
use #freeAfterUse and if I do “Identity := nil” at some point free
should be called
on the old string. Is there anything in the system that sets the address
to 0x0 after
the image is starting?
As the thing is a NBExternalAddress, there is a
finalize
self free
which will do the free call when the Identity will be gc'd.
As for the statup/shutdown, maybe
startUp: resuming
shutDown: quitting
methods on the class side of your facility will do the necessary things.
I am pretty sure the address would be pointing to invalid crap upon image
restart.
Doing free too many times will just raise an error I guess (which you can
catch).
free: address
sema critical: [ | block |
block := reservedBlocks removeKey: address ifAbsent: [
self error: 'Unable to find a memory block with given address' ].
block makeFreeFor: self ]
HTH
Phil
thanks
holger