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
===========================================================================




Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to