Issue #115 new

A way to allocate and initialize unmanaged memory with ffi.new-like syntax

Tyler Wade
created an issue

I would like to see cffi provide a way to allocate/initialize memory in a way similar to ffi.new, but without the memory being freed automatically by cffi. My use case is returning a string from a callback. Using ffi.new won't work because cffi will free the string automatically and while I can use malloc and copy the string manually, being able to simply write return ffi.unmanaged_new('char*', some_str) would be much easier and more readable. (I'm not suggesting the name unmanaged_new.)

Comments (3)

  1. Armin Rigo

    It opens a lot of questions: would the memory be allocated by the C malloc so that the C code can use free on it? What about systems that use a different pair of functions (more common on Windows but exists on Linux too)? Or would you have to use ffi.unmanaged_free()? In the latter case it might be enough to maintain the result of ffi.new() alive by storing it somewhere temporarily.

  2. Tyler Wade reporter

    Fair enough. A couple of possible alternatives/compromises:

    Have ffi.unmanaged_new take a malloc parameter: ffi.unmanaged_new('char*', lib.malloc, some_str)

    Or

    Provide a function for initializing a chunk of memory: ffi.memcpy(some_ptr, 'char*', some_str). This is potentially more useful, but it may be hard for the user to know how big the chunk of memory needs to be.

    Either would work fine for me.

  3. Armin Rigo

    Assignment already supports most of the same syntax:

    ffi.cdef("struct s { int x, y, z; }")
    p = ffi.new("struct s *")    # or any other way
    p[0] = [4, 5, 6]
    p[0] = {'x': 4, 'z': 6}
    
    a = ffi.new("char[]", 10)
    a[0:6] = "foobar"
    
    a = ffi.new("int[]", 10)
    a[0:3] = [10, 20, 30]
    
  4. Log in to comment