1 /* Copyright (c) 2007 Timothy Wall, All Rights Reserved 2 * 3 * The contents of this file is dual-licensed under 2 4 * alternative Open Source/Free licenses: LGPL 2.1 or later and 5 * Apache License 2.0. (starting with JNA version 4.0.0). 6 * 7 * You can freely decide which license you want to apply to 8 * the project. 9 * 10 * You may obtain a copy of the LGPL License at: 11 * 12 * http://www.gnu.org/licenses/licenses.html 13 * 14 * A copy is also included in the downloadable source code package 15 * containing JNA, in file "LGPL2.1". 16 * 17 * You may obtain a copy of the Apache License at: 18 * 19 * http://www.apache.org/licenses/ 20 * 21 * A copy is also included in the downloadable source code package 22 * containing JNA, in file "AL2.0". 23 */ 24 package com.sun.jna.ptr; 25 26 import java.lang.reflect.Method; 27 28 import com.sun.jna.Memory; 29 import com.sun.jna.Pointer; 30 import com.sun.jna.PointerType; 31 32 /** 33 * Provides generic "pointer to type" functionality, often used in C code to 34 * return values to the caller in addition to a function result. 35 * <p> 36 * Derived classes must define <code>setValue(<T>)</code> and 37 * <code><T> getValue()</code> methods which write to/read from the 38 * allocated memory. 39 * <p> 40 * This class derives from PointerType instead of Memory in order to restrict 41 * the API to only <code>getValue/setValue</code>. 42 * <p> 43 * NOTE: this class would ideally be replaced by a generic. 44 */ 45 public abstract class ByReference extends PointerType { 46 47 /** 48 * Allocates memory at this pointer, to contain the pointed-to value. 49 * 50 * @param dataSize 51 * The number of bytes to allocate. Must match the byte size of 52 * <code>T</code> in the derived class 53 * <code>setValue(<T>)</code> and 54 * <code><T> getValue()</code> methods. 55 */ ByReference(int dataSize)56 protected ByReference(int dataSize) { 57 setPointer(new Memory(dataSize)); 58 } 59 60 @Override toString()61 public String toString() { 62 try { 63 Method getValue = getClass().getMethod("getValue"); 64 Object value = getValue.invoke(this); 65 if (value == null) { 66 return String.format("null@0x%x", Pointer.nativeValue(getPointer())); 67 } 68 return String.format("%s@0x%x=%s", value.getClass().getSimpleName(), Pointer.nativeValue(getPointer()), 69 value); 70 } catch (Exception ex) { 71 return String.format("ByReference Contract violated - %s#getValue raised exception: %s", 72 getClass().getName(), ex.getMessage()); 73 } 74 } 75 } 76