Difference between revisions of "Data:getFFIPointer"

(Created page with "{{newin|11.3|113|type=function}} Gets an [http://luajit.org/ext_ffi.html FFI] pointer to the Data. This function should be preferred instead of Data:getPointer becaus...")
 
m (add example from post)
 
(2 intermediate revisions by one other user not shown)
Line 5: Line 5:
 
[[light userdata]] which can't store more all possible memory addresses on some new ARM64
 
[[light userdata]] which can't store more all possible memory addresses on some new ARM64
 
architectures, when LuaJIT is used.
 
architectures, when LuaJIT is used.
 +
{{notice|Use at your own risk. Directly reading from and writing to the raw memory owned by the Data will bypass any safety checks and thread-safety the Data might normally have.}}
 
== Function ==
 
== Function ==
 
=== Synopsis ===
 
=== Synopsis ===
Line 14: Line 15:
 
=== Returns ===
 
=== Returns ===
 
{{param|cdata|pointer|A raw <code>void*</code> pointer to the Data, or <code>nil</code> if FFI is unavailable.}}
 
{{param|cdata|pointer|A raw <code>void*</code> pointer to the Data, or <code>nil</code> if FFI is unavailable.}}
 +
 +
=== Example ===
 +
 +
<source lang="lua">
 +
local mem = love.data.newByteData(2 ^ 30)                      -- 1 GB
 +
local ptr = ffi.cast('uint8_t*', mem:getFFIPointer())          -- grab byte pointer
 +
local byte100 = ptr[99]                                        -- get the 100th byte out of the allocated data mem
 +
local uint32array = ffi.cast('uint32_t*', mem:getFFIPointer()) -- grab 4-byte integer pointer
 +
uint32array[0] = 0xdeadbeef                                    -- treat mem as integer array, assign to 1st position
 +
</source>
 +
 +
As an example usage, allocate memory and grab an FFI pointer.  The pointer can be cast to any FFI ctype one wishes in order to access the memory accordingly.  A pointer to the data could be cast to type <code>uint8_t*</code>, allowing one to access that memory like a 0-based sequential Lua table that contains byte values.  Or the same memory could be treated as an array of 32-bit integers by recasting the pointer to <code>uint32_t*</code> .  Note that these pointers will be invalid if the underlying ByteData goes out of scope.
 +
 
== See Also ==
 
== See Also ==
 
* [[parent::Data]]
 
* [[parent::Data]]
Line 22: Line 36:
 
{{#set:Description=Gets an FFI pointer to the Data.}}
 
{{#set:Description=Gets an FFI pointer to the Data.}}
 
== Other Languages ==
 
== Other Languages ==
{{i18n|Data:getPointer}}
+
{{i18n|Data:getFFIPointer}}

Latest revision as of 00:35, 16 December 2021

Available since LÖVE 11.3
This function is not supported in earlier versions.

Gets an FFI pointer to the Data.

This function should be preferred instead of Data:getPointer because the latter uses light userdata which can't store more all possible memory addresses on some new ARM64 architectures, when LuaJIT is used.

O.png Use at your own risk. Directly reading from and writing to the raw memory owned by the Data will bypass any safety checks and thread-safety the Data might normally have.  


Function

Synopsis

pointer = Data:getFFIPointer( )

Arguments

None.

Returns

cdata pointer
A raw void* pointer to the Data, or nil if FFI is unavailable.

Example

local mem = love.data.newByteData(2 ^ 30)                      -- 1 GB
local ptr = ffi.cast('uint8_t*', mem:getFFIPointer())          -- grab byte pointer
local byte100 = ptr[99]                                        -- get the 100th byte out of the allocated data mem
local uint32array = ffi.cast('uint32_t*', mem:getFFIPointer()) -- grab 4-byte integer pointer
uint32array[0] = 0xdeadbeef                                    -- treat mem as integer array, assign to 1st position

As an example usage, allocate memory and grab an FFI pointer. The pointer can be cast to any FFI ctype one wishes in order to access the memory accordingly. A pointer to the data could be cast to type uint8_t*, allowing one to access that memory like a 0-based sequential Lua table that contains byte values. Or the same memory could be treated as an array of 32-bit integers by recasting the pointer to uint32_t* . Note that these pointers will be invalid if the underlying ByteData goes out of scope.

See Also

Other Languages