On 2010-04-03, at 6:36 AM, Schwab,Wilhelm K wrote: > Andreas, John, anybody, > > I need to find the address of a "function" (it is in fact a global structure > pointer somewhere in memory) and pass it to another function.
Well some sample code from the objective C bridge. This doesn't use any "C"
code or the FFI/Alien logic since it was targeted
towards the iPhone and FFI and Alien aren't supported.
This creates a byteArray that contains the (length) bytes from a known global
structure identified by linker name.
However the primitiveGetAddressFromEntryPointString returns a memory address as
a large positive integer.
"Pass in the name in a String, indicate the length of the data element"
fetchByteArrayConstantCalled: aString withLength: length
| address |
address := self findAddressForString: aString.
address = 0 ifTrue: [^self error: 'Address of constant not found'].
^self fetchByteArrayFrom: address length: length.
findAddressForString: aNameString
"ObjectiveCBridge findAddressForString: 'CGRectZero'"
| externalAddress |
externalAddress := self primitiveGetAddressFromEntryPointString:
aNameString.
^externalAddress
primitiveGetAddressFromEntryPointString: aString
<primitive: 'primitiveGetAddressFromEntryPointString' module:
'ObjectiveCPlugin'>
self primitiveFailed
"The plugin code is below, first we need to move the name from a smalltalk
string to a C String. To
do this we construct a strlcpy using a fake call to str:l:cpy: then we
invoke dl:sym: which is really dlSym(-2,entryPointName)
This gives back the address of the data. Remember to create a 64bit positive
number out of it since we could be on a 64bit system
primitiveGetAddressFromEntryPointString: aEntryPointName
| entryPointNameLength fn entryPointName |
self primitive: 'primitiveGetAddressFromEntryPointString'
parameters: #(String).
self var: 'entryPointName' declareC: 'char entryPointName[256]'.
self var: 'fn' declareC: 'void * fn'.
entryPointNameLength := interpreterProxy slotSizeOf: aEntryPointName
cPtrAsOop.
entryPointNameLength > 256 ifTrue: [^interpreterProxy
positive64BitIntegerFor: 0].
self str: entryPointName l: aEntryPointName cpy: entryPointNameLength+1.
fn := self dl: -2 sym: entryPointName.
^interpreterProxy positive64BitIntegerFor: (self cCoerce: fn to:
'usqInt')
"Given an address lets fetch N bytes from it, the ByteArray is create by the
primitive "
fetchByteArrayFrom: anAddress length: length
^self nsInvocationGetStructureType: anAddress length: length
nsInvocationGetStructureType: bufferAddressOop length: length
^self primitiveNSInvocationGetStructureType: bufferAddressOop length:
length
primitiveNSInvocationGetStructureType: bufferAddressOop length: length
<primitive: 'primitiveNSInvocationGetStructureType' module:
'ObjectiveCPlugin'>
self primitiveFailed
"64bits again for 64 bit systems, Use the fake construct of me:m:cpy: to do
the memcpy"
primitiveNSInvocationGetStructureType: bufferAddressOop length: length
| bufferPointer newByteArray |
self primitive: 'primitiveNSInvocationGetStructureType'
parameters: #(Oop SmallInteger).
self var: 'bufferPointer' declareC: 'char ** bufferPointer'.
self var: 'buffer' declareC: 'char * buffer'.
bufferPointer := self cCoerce: (interpreterProxy positive64BitValueOf:
bufferAddressOop) to: 'void *'.
interpreterProxy failed ifTrue: [^nil].
newByteArray := interpreterProxy
instantiateClass: interpreterProxy classByteArray
indexableSize: length.
self me: (interpreterProxy arrayValueOf: newByteArray)
m: bufferPointer
cpy: length. "void * memcpy(void *restrict s1, const void
*restrict s2, size_t n)"
^newByteArray
--
===========================================================================
John M. McIntosh <[email protected]> Twitter: squeaker68882
Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com
===========================================================================
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Pharo-project mailing list [email protected] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
