Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Forth Mac > Re: how do crea...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 8 of 8 Topic 144 of 161
Post > Topic >>

Re: how do create a shared library from macforth app

by Roelf Toxopeus <these3rt0only@[EMAIL PROTECTED] > May 28, 2007 at 12:37 PM

In article <1180311684.400694.217990@[EMAIL PROTECTED]
>,
 chris@[EMAIL PROTECTED]
 wrote:

> Hi again Roelf,
> 
> Thanks for your suggestion and the code example.  I have the
> op****tunity to experiment more with it today with a C programmer, and
> maybe he can shed some light on it.
> 
> I'm wondering if I can make a bundle to which both of these apps
> belong - I'll have to read more about that in Apples tech notes.
> 
> For the purpose of testing I'm thinking that the calling app could be
> a MacForth turnkey, and I may be able to understand this better than
> trying to get my head around C or C++
> 
> Back when I make some progress.
> 
> Cheers
> 
> Chris

Hi Chris,

I was just about to re****t about my days of headbanging.
None of this is fixing the Intel native question I'm afraid.

First, I agree that turnkeying MF in a shared library a.k.a. framework
or bundle, is the simplest and most straight forward way. The vendor is
sorely missed!!!

Now , the problem I ran against has to do with the process memory spaces,
especially moving pointers to executable code around.

BTW, sharing data space between processes is no problem.

What I tried might be of help.
My apologies to your C programmer for the code :-)

See if new app is launched in memory space calling app.
First I compiled the following C code in XCode.app as a framework
and put it in /Library/Frameworks/

<c code>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdio.h>


typedef void (*FunctionPtr)(void);

FunctionPtr foo;

short setCallBack( FunctionPtr callBackFunctionPtr )
{
   foo = callBackFunctionPtr;
   return( 0 );
}

short runCallBack()
{
   foo();
   return( 0 );
}

short init()
{
   // Launch MF
   OSErr err;
   OSErr err_fsref;
   FSRef fileRef;
   err_fsref = FSPathMakeRef((StringPtr)"/Users/roelf/Applications/F O R 
T H/MacForth/C A R B O N/testing MF/Carbon MacForth 6.0.5/My Extended 
Kernel pre", &fileRef, NULL);
      
     if (err_fsref == noErr) {
          err = LSRegisterFSRef(&fileRef, true);
     if (err_fsref == noErr)
         err = LSOpenFSRef(&fileRef, NULL);
     }
   return( 0 );
}
</c code>
Next I launched  a copy of MacForth, and loaded the framework, im****ted
the init call and execute it:

<forth code>

\ include the shared framework or bundle
globalbundle /library/frameworks/test3.framework
\ select it
test3.framework

\ im****t needed function
0 machofunc _init

_init drop
</forth code>

The launched MF is another version btw.
In the new MF, here MF2, I try to connect to the same framework, not a 
copy!

<forth code>
1 externfunc _CFBundleGetBundleWithIdentifier ( CFStringRef:bundleID -- 
CFBundleRef )

\ id comes from the plist in bundle, look for CFBundleIdentifier
0" com.apple.carbonframeworktemplate" >cfstring 
_CFBundleGetBundleWithIdentifier .
</forth code>

It returns zero.
Just to be sure, in MF2:

<forth code>
globalbundle /library/frameworks/test3.framework

\ select it
test3.framework

\ access data in bundle
2 externfunc _CFBundleGetDataPointerForName ( CFBundleRef CFStringRef -- 
datapointer )

0" com.apple.carbonframeworktemplate" >cfstring 
_CFBundleGetBundleWithIdentifier
0" foo" >cfstring _CFBundleGetDataPointerForName .s
constant foo

foo ?
0 ok <0>
1234 foo !
ok <0>
</forth code>

In MF1 get 'foo' in the same way as in MF2 and fetch its content:
0, zero, nada, nothing.

So we don't share the same memory space. At least this is not the
way to do it.

Don't give up.
Look in the lower system calls: unix, mach, bsd.
One way of sharing memory between different applications is:

<forth code>
\ ---------- both processes ------------
\ fast and dirty, for quick testing, no semaphores etc.
\ not complete, no detaching implemented, memory leaks ;-)

system.framework

3 machofunc _shmget ( key size flag -- id )
3 machofunc _shmat ( id addr flag -- addr )

\ fixed settings for now
001000 constant IPC_CREAT
IPC_CREAT 0666 or constant SHMFLAG

\ change to usage
256 constant SHMSIZE
ascii share constant SHMKEY

: share ( key size -- addr )
   shmflag _shmget dup -1 = abort" no sharing"
   0 dup _shmat dup -1 = abort" no attaching" ;

prior.stream

\ ---------- this process ------------

shmkey shmsize share value myshares

c" going down" myshares over count nip char+ move
myshares count type

prior.stream

\ ---------- other process ------------

shmkey shmsize share value hisshares

hisshares count type

prior.stream
</forth code>

Launch two MF's, include the stuff for both apps and execute 'this' in
MF1 and 'other' in MF2.

Alas, storing xt's in the shared memory and have them executed by the
other MF, won't work. 
Ways to (re)mapping (virtual) memory areas is what's needed I guess.

Still there is a way:
Launch the turnkeyed MF, MF declares a piece of shared memory. MF goes
in the following loop:      begin  break  myshares count evaluate   again

A calling app connects to the shared memory, puts the wanted action
 into it, wakes MF and there you go.

The sleeping/breaking    waking/kicking  goes via unix signalling.

<forth code>
System.framework

lacking _getpid 0 machofunc _getpid ( -- pid )
lacking _kill 2 machofunc _kill  ( pid n -- ret )

\ avoid overloading Forth Multitasking words Stop, Sleep
\ 17 = SIGSTOP ( stop/suspend a process )
: HALT ( pid -- ret )   17 _kill drop ;

\ halt yourself
: BREAK ( -- )   _getpid halt drop ;

\ avoid overloading Forth Multitasking word Wake
\ 19 = SIGCONT ( continue a stopped process )
: KICK ( pid -- ret )   19 _kill drop ;

</forth code>

The calling app does a 19 kill to wake MF, you need the MF's pid though.
Several ways and means to do that ;-)

If you use a framework as global interface:
The init function in the framework could be extended to connect to
the shared memory. Other ex****ted calls just 'set' the memory and
kick the turnkeyed MF into action.

Thoughts:
Evaluating the buffer might be too much overhead or overkill, simply
passing an index to an execution table could be enough. Which might
also help in the size of the turnkey, no need for the interpreter.
MF's output can use a shared buffer as well, obviously.

Not tried in this context but interesting to look into: fork, clone, exec

So far for now.

-r
 




 8 Posts in Topic:
how do create a shared library from macforth app
chris@[EMAIL PROTECTED]   2007-05-17 19:24:56 
Re: how do create a shared library from macforth app
Roelf Toxopeus <these3  2007-05-21 09:09:02 
Re: how do create a shared library from macforth app
Roelf Toxopeus <these3  2007-05-21 13:49:01 
Re: how do create a shared library from macforth app
chris@[EMAIL PROTECTED]   2007-05-21 23:58:48 
Re: how do create a shared library from macforth app
chris@[EMAIL PROTECTED]   2007-05-22 00:23:15 
Re: how do create a shared library from macforth app
Roelf Toxopeus <these3  2007-05-22 21:49:21 
Re: how do create a shared library from macforth app
chris@[EMAIL PROTECTED]   2007-05-27 17:21:24 
Re: how do create a shared library from macforth app
Roelf Toxopeus <these3  2007-05-28 12:37:48 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sat Nov 22 14:34:18 CST 2008.