[Mono-list] Mixing managed and unmanaged code

Jonathan Pryor jonpryor@vt.edu
Wed, 08 Oct 2003 21:30:21 -0400


You might find my P/Invoke guide useful:

	http://www.go-mono.com/docs/monodoc.ashx?tlink=5@xhtml%3Ahtml%2Fen%2Fwrapping%2Finterop.html

Or, you might know it all.

<shameless-plug>
Either way, I can use the feedback!
</shameless-plug>

As for your question ("Is the 'args' IntPtr...allocated on the stack"):
yes.  System.IntPtr is a value-type, and all value types are allocated
"inline".

Inline, meaning, on the stack (in the case of functions), or fully
within a class/structure instance (no pointers involved).

Of course, you can box it, thus making it heap-allocated, but in your
example it's certainly stack-allocated.

As for whether the Ruby GC will collect the value referenced...  You
mention earlier that the Ruby GC scans the stack for pointers, so
wouldn't it find the IntPtr on the stack and try to collect it?

.NET should behave the same way as Mono.  If it doesn't, it's a Mono
bug.

As for stack sharing between managed and unmanaged code, that depends on
the code. :-)

For "typical" unmanaged code that *actually uses the runtime stack*
(true for most languages), then managed and unmanaged code will share
the stack.

However, some languages (early Lisp dialects come to mind) do not use
the runtime stack, preferring to use the heap instead, so all bets are
off when interacting with them.  You're not likely to see this, so I
wouldn't worry about it.

 - Jon

On Wed, 2003-10-08 at 10:24, Thomas Sondergaard wrote:
> I am working on an interop solution between ruby and the .net CLR. Ruby has
> a conservative garbage collector that scans the stack for pointers into it's
> heap of managed memory (not .net managed, ruby managed). When I mix managed
> and unmanaged code I need to make sure that the ruby garbage collector wont
> reap ruby objects referenced in managed code and vice versa.
> 
> Objects are passed both ways from ruby to .net and the other way
> by-reference using proxies. These proxies use GCHandle's and the ruby
> equivalent of CGHandle. However inside the marshalling and interfacing code
> I manipulate ruby objects using managed code like in the send() method
> below, which is used to invoke ruby methods on a ruby object from
> .net:
> 
> public class Object {
> 
>     public Object(IntPtr handle) {
>         _handle = handle;
>         RubyAPI.ruby_gchandle_alloc(_handle);
>     }
> 
>     ~Object() {
>         RubyAPI.ruby_gchandle_free(_handle);
>     }
> 
>     public virtual object send(string cmd, object[] args) {
>         IntPtr args = Marshal.arrayFromDotNet(argsArray);
>         return Marshal.toDotNet(RubyAPI.rb_apply(_handle,
> RubyAPI.rb_intern(cmd), args));
>     }
> 
>     private IntPtr _handle;
> 
> }
> 
> Now here is the real question: Is the 'args' IntPtr in the send() method
> above allocated on the stack, so I can be sure that the ruby gc wont collect
> the value referenced? Incidently, do you reckon this will be the case for
> Microsofts CLR (too)?
> 
> Is there some magic in the way that managed and unmanaged code is mixed? It
> executes on the same stack, right?
> 
> Thank you!
> 
> Thomas Sondergaard
> http://rubydotnet.sourceforge.net
> 
> 
> 
> _______________________________________________
> Mono-list maillist  -  Mono-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list