more notes about nlffi and memory management

brian <briand-/[email protected]> Fri, 9 Mar 2007 22:24:24 -0800
Newsgroups gmane.comp.lang.sml.smlnj
Message-ID <[email protected]>
I took the code which is giving me trouble on the PPC and it works  
just fine on intel, which I seem to remember was the case.

So I suppose this means Matthias has not had time to look into it :-(

In the meantime I developed a not-too-ugly work-around and want it on  
the list for future nlffi users.

I simply use the standard malloc and free

void *malloc(long);
void free(void *);

The pointer is allocated thusly:

val m = C.Ptr.cast (C.T.pointer C.T.double) (F_malloc.f  
(Int32.fromInt n))

Explanations:

(F_malloc.f (Int32.fromInt (n*4)))

accesses the malloc statement.  Make sure you use the correct  
allocation size for your datatype !!

To actually use the pointer to access memory you will really need to  
use a rw version:

C.Ptr.rw m

Next is the key operation and implements the conversion from 'void *'  
to 'double *'

C.Ptr.cast (C.T.pointer C.T.double)

Then the pointer must be re-cast when using free, since free is  
expecting a 'void *'

  F_free.f (C.Ptr.inject b1);

The complete code is at the end of the e-mail

Brian

fun memtest() =
     let fun set(p, i, x) = C.Set.double (C.Ptr.|*| (C.Ptr.|+| (p,  
i)), x)
         fun dprint (p, i) =
             let val x = C.Get.double (C.Ptr.|*| (C.Ptr.|+| (p, i)))
             in
                 print (Real.toString x)
             end
         fun fromArray(values) =
             let val n = Array.length(values)
                 (* val m = C.alloc C.T.double (Word.fromInt n) *)
                 (* notice the pointer conversion from void* to  
double *)
                 val m = C.Ptr.cast (C.T.pointer C.T.double)  
(F_malloc.f (Int32.fromInt (n*4)))
                 val _ = Array.appi (fn (i, x) => set(m, i, x)) values
             in
                 (* return a read-write version of the pointer *)
                 C.Ptr.rw m
             End
         val a1 = Array.fromList([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
         val a2 = Array.fromList([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
         val b1 = fromArray(a1)
         val b2 = fromArray(a2)
     in
         Vector.appi (fn (i,x) => (dprint(b1, i); print "\n")) # 
[0,1,2,3,4,5,6];
         F_free.f (C.Ptr.inject b1);
         F_free.f (C.Ptr.inject b2);
         ()
     end


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV