How to use the ref-napi.sizeof function in ref-napi

To help you get started, we’ve selected a few ref-napi examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github node-ffi-napi / node-ffi-napi / lib / type.js View on Github external
numElements += 1;
      }
    }

    // hand-crafting a null-terminated array here.
    // XXX: use "ref-array"?
    const size = ref.sizeof.pointer * (numElements + 1); // +1 because of the NULL terminator
    const elements = ffi_type.elements = Buffer.alloc(size);
    let index = 0;
    for (let i = 0; i < numFields; i++) {
      field = fields[fieldNames[i]];
      if (field.type.fixedLength > 0) {
        // a fixed-length "ref-array" type
        ffi_type_ptr = Type(field.type.type);
        for (var j = 0; j < field.type.fixedLength; j++) {
          elements.writePointer(ffi_type_ptr, (index++) * ref.sizeof.pointer);
        }
      } else {
        ffi_type_ptr = Type(field.type);
        elements.writePointer(ffi_type_ptr, (index++) * ref.sizeof.pointer);
      }
    }
    // final NULL pointer to terminate the Array
    elements.writePointer(ref.NULL, index * ref.sizeof.pointer);
    // also set the `ffi_type` property to that it's cached for next time
    ret = type.ffi_type = ffi_type.ref();
  }

  if (!ret && type.name) {
    // handle "ref" types other than the set that node-ffi is using (i.e.
    // a separate copy)
    if ('CString' == type.name) {
github node-ffi-napi / node-ffi-napi / lib / cif.js View on Github external
'use strict';
/**
 * Module dependencies.
 */

var Type = require('./type');
const assert = require('assert');
const debug = require('debug')('ffi:cif');
const ref = require('ref-napi');
const bindings = require('./bindings');
const POINTER_SIZE = ref.sizeof.pointer;
const ffi_prep_cif = bindings.ffi_prep_cif;
const FFI_CIF_SIZE = bindings.FFI_CIF_SIZE;
const FFI_DEFAULT_ABI = bindings.FFI_DEFAULT_ABI;
  // status codes
const FFI_OK = bindings.FFI_OK;
const FFI_BAD_TYPEDEF = bindings.FFI_BAD_TYPEDEF;
const FFI_BAD_ABI = bindings.FFI_BAD_ABI;

/**
 * JS wrapper for the `ffi_prep_cif` function.
 * Returns a Buffer instance representing a `ffi_cif *` instance.
 */

const cifs = [];
function CIF (rtype, types, abi) {
  debug('creating `ffi_cif *` instance');
github node-ffi-napi / node-ffi-napi / lib / ffi.js View on Github external
});

// make `size_t` use the "ffi_type_pointer"
ref.types.size_t.ffi_type = bindings.FFI_TYPES.pointer;

// make `Utf8String` use "ffi_type_pointer"
const CString = ref.types.CString || ref.types.Utf8String;
CString.ffi_type = bindings.FFI_TYPES.pointer;

// make `Object` use the "ffi_type_pointer"
ref.types.Object.ffi_type = bindings.FFI_TYPES.pointer;

// libffi is weird when it comes to long data types (defaults to 64-bit),
// so we emulate here, since some platforms have 32-bit longs and some
// platforms have 64-bit longs.
switch (ref.sizeof.long) {
  case 4:
    ref.types.ulong.ffi_type = bindings.FFI_TYPES.uint32;
    ref.types.long.ffi_type = bindings.FFI_TYPES.int32;
    break;
  case 8:
    ref.types.ulong.ffi_type = bindings.FFI_TYPES.uint64;
    ref.types.long.ffi_type = bindings.FFI_TYPES.int64;
    break;
  default:
    throw new Error('unsupported "long" size: ' + ref.sizeof.long);
}

/**
 * Alias the "ref" types onto ffi's exports, for convenience...
 */
github node-ffi-napi / node-ffi-napi / lib / _foreign_function.js View on Github external
function ForeignFunction (cif, funcPtr, returnType, argTypes) {
  debug('creating new ForeignFunction', funcPtr);

  const numArgs = argTypes.length;
  const argsArraySize = numArgs * POINTER_SIZE;

  // "result" must point to storage that is sizeof(long) or larger. For smaller
  // return value sizes, the ffi_arg or ffi_sarg integral type must be used to
  // hold the return value
  const resultSize = returnType.size >= ref.sizeof.long ? returnType.size : FFI_ARG_SIZE;
  assert(resultSize > 0);

  /**
   * This is the actual JS function that gets returned.
   * It handles marshalling input arguments into C values,
   * and unmarshalling the return value back into a JS value
   */

  const proxy = function () {
    debug('invoking proxy function');

    if (arguments.length !== numArgs) {
      throw new TypeError('Expected ' + numArgs +
          ' arguments, got ' + arguments.length);
    }
github node-ffi-napi / node-ffi-napi / lib / _foreign_function.js View on Github external
'use strict';
/**
 * Module dependencies.
 */

const assert = require('assert');
const debug = require('debug')('ffi:_ForeignFunction');
const ref = require('ref-napi');
const bindings = require('./bindings');
const POINTER_SIZE = ref.sizeof.pointer;
const FFI_ARG_SIZE = bindings.FFI_ARG_SIZE;


function ForeignFunction (cif, funcPtr, returnType, argTypes) {
  debug('creating new ForeignFunction', funcPtr);

  const numArgs = argTypes.length;
  const argsArraySize = numArgs * POINTER_SIZE;

  // "result" must point to storage that is sizeof(long) or larger. For smaller
  // return value sizes, the ffi_arg or ffi_sarg integral type must be used to
  // hold the return value
  const resultSize = returnType.size >= ref.sizeof.long ? returnType.size : FFI_ARG_SIZE;
  assert(resultSize > 0);

  /**
github node-ffi-napi / node-ffi-napi / lib / foreign_function_var.js View on Github external
'use strict';
/**
 * Module dependencies.
 */

const CIF_var = require('./cif_var');
const Type = require('./type');
const _ForeignFunction = require('./_foreign_function');
const assert = require('assert');
const debug = require('debug')('ffi:VariadicForeignFunction');
const ref = require('ref-napi');
const bindings = require('./bindings');
const POINTER_SIZE = ref.sizeof.pointer;
const FFI_ARG_SIZE = bindings.FFI_ARG_SIZE;

/**
 * For when you want to call to a C function with variable amount of arguments.
 * i.e. `printf()`.
 *
 * This function takes care of caching and reusing ForeignFunction instances that
 * contain the same ffi_type argument signature.
 */

function VariadicForeignFunction (funcPtr, returnType, fixedArgTypes, abi) {
  debug('creating new VariadicForeignFunction', funcPtr);

  // the cache of ForeignFunction instances that this
  // VariadicForeignFunction has created so far
  const cache = {};
github node-ffi-napi / node-ffi-napi / lib / cif_var.js View on Github external
'use strict';
/**
 * Module dependencies.
 */

const Type = require('./type');
const assert = require('assert');
const debug = require('debug')('ffi:cif_var');
const ref = require('ref-napi');
const bindings = require('./bindings');
const POINTER_SIZE = ref.sizeof.pointer;
const ffi_prep_cif_var = bindings.ffi_prep_cif_var;
const FFI_CIF_SIZE = bindings.FFI_CIF_SIZE;
const FFI_DEFAULT_ABI = bindings.FFI_DEFAULT_ABI;
  // status codes
const FFI_OK = bindings.FFI_OK;
const FFI_BAD_TYPEDEF = bindings.FFI_BAD_TYPEDEF;
const FFI_BAD_ABI = bindings.FFI_BAD_ABI;

/**
 * JS wrapper for the `ffi_prep_cif_var` function.
 * Returns a Buffer instance representing a variadic `ffi_cif *` instance.
 */

function CIF_var (rtype, types, numFixedArgs, abi) {
  debug('creating `ffi_cif *` instance with `ffi_prep_cif_var()`');
github node-ffi-napi / node-ffi-napi / lib / ffi.js View on Github external
ref.types.Object.ffi_type = bindings.FFI_TYPES.pointer;

// libffi is weird when it comes to long data types (defaults to 64-bit),
// so we emulate here, since some platforms have 32-bit longs and some
// platforms have 64-bit longs.
switch (ref.sizeof.long) {
  case 4:
    ref.types.ulong.ffi_type = bindings.FFI_TYPES.uint32;
    ref.types.long.ffi_type = bindings.FFI_TYPES.int32;
    break;
  case 8:
    ref.types.ulong.ffi_type = bindings.FFI_TYPES.uint64;
    ref.types.long.ffi_type = bindings.FFI_TYPES.int64;
    break;
  default:
    throw new Error('unsupported "long" size: ' + ref.sizeof.long);
}

/**
 * Alias the "ref" types onto ffi's exports, for convenience...
 */

exports.types = ref.types;

// Include our other modules
exports.version = bindings.version;
exports.CIF = require('./cif');
exports.CIF_var = require('./cif_var');
exports.Function = require('./function');
exports.ForeignFunction = require('./foreign_function');
exports.VariadicForeignFunction = require('./foreign_function_var');
exports.DynamicLibrary = require('./dynamic_library');
github node-ffi-napi / node-ffi-napi / lib / callback.js View on Github external
const callback = _Callback(cif, retType.size, argc, errorReportCallback, (retval, params) => {
    debug('Callback function being invoked')
    try {
      const args = [];
      for (var i = 0; i < argc; i++) {
        const type = argTypes[i];
        const argPtr = params.readPointer(i * ref.sizeof.pointer, type.size);
        argPtr.type = type;
        args.push(argPtr.deref());
      }

      // Invoke the user-given function
      const result = func.apply(null, args);
      try {
        ref.set(retval, 0, result, retType);
      } catch (e) {
        e.message = 'error setting return value - ' + e.message;
        throw e;
      }
    } catch (e) {
      return e;
    }
  });
github node-ffi-napi / node-ffi-napi / lib / function.js View on Github external
this.retType = ref.coerceType(retType);
  this.argTypes = argTypes.map(ref.coerceType);
  this.abi = null == abi ? bindings.FFI_DEFAULT_ABI : abi;
}

/**
 * The "ffi_type" is set for node-ffi functions.
 */

Function.prototype.ffi_type = bindings.FFI_TYPES.pointer;

/**
 * The "size" is always pointer-sized.
 */

Function.prototype.size = ref.sizeof.pointer;

/**
 * The "alignment" is always pointer-aligned.
 */

Function.prototype.alignment = ref.alignof.pointer;

/**
 * The "indirection" is always 1 to ensure that our get()/set() get called.
 */

Function.prototype.indirection = 1;

/**
 * Returns a ffi.Callback pointer (Buffer) of this function type for the
 * given `fn` Function.