Table of Contents
String
Buffers, Memory, Arrays and Pointers
Variable parameters
Home Java javaTutorial Java's JNA type mapping attention to details and usage

Java's JNA type mapping attention to details and usage

Apr 18, 2023 pm 05:07 PM
java jna

String

The first is the mapping of String. String in JAVA actually corresponds to two native types: const char* and const wchar_t*. By default String will be converted to char*.

char is an ANSI data type, and wchar_t is a Unicode character data type, also called a wide character.

If JAVA's unicode characters are to be converted into a char array, some encoding operations need to be performed. If jna.encoding is set, the set encoding method will be used for encoding. By default, the encoding method is "UTF8".

If it is WString, Unicode values ​​can be copied directly to WString without any encoding.

Let’s look at a simple example first:

char* returnStringArgument(char *arg) {
  return arg;
}

wchar_t* returnWStringArgument(wchar_t *arg) {
  return arg;
}
Copy after login

The above native code can be mapped to:

String returnStringArgument(String s);
WString returnWStringArgument(WString s);
Copy after login

Let’s look at a different example. If the definition of the native method is like this :

int getString(char* buffer, int bufsize);

int getUnicodeString(wchar_t* buffer, int bufsize);
Copy after login

We have defined two methods, the parameters of which are char* and wchar_t*.

Next, let’s take a look at how to define method mapping in JAVA:

// Mapping A:
int getString(byte[] buf, int bufsize);
// Mapping B:
int getUnicodeString(char[] buf, int bufsize);
Copy after login

The following is the specific use:

byte[] buf = new byte[256];
int len = getString(buf, buf.length);
String normalCString = Native.toString(buf);
String embeddedNULs = new String(buf, 0, len);
Copy after login

Some students may ask, since in JAVA String can be converted into char*, why do we need to use byte array here?

This is because the getString method needs to modify the contents of the incoming char array, but because String is immutable, String cannot be used directly here. We need to use a byte array.

Then we use Native.toString(byte[]) to convert the byte array into a JAVA string.

Look at another return value situation:

// Example A: Returns a C string directly
const char* getString();
// Example B: Returns a wide character C string directly
const wchar_t* getString();
Copy after login

Generally, if the native method returns string directly, we can use String for mapping:

// Mapping A
String getString();
// Mapping B
WString getString();
Copy after login

If the native code After allocating memory space for String, we'd better use Pointer in JNA as the return value, so that we can release the occupied space at some point in the future, as shown below:

Pointer getString();
Copy after login

Buffers, Memory, Arrays and Pointers

When do you need to use Buffers and Memory?

Generally, if an array of basic data is passed as a parameter to a function, you can use the basic class directly in JAVA array instead. But if the native method still needs to access the array after the method returns (save the pointer to the array), in this case it is not appropriate to use the array of the base class. In this case, we need to use ByteBuffers or Memory .

We know that arrays in JAVA have lengths, but for native methods, the returned array is actually a pointer to the array, and we do not know the length of the returned array, so if the native method If an array pointer is returned, it is inappropriate to use arrays for mapping in JAVA code. In this case, you need to use Pointer.

Pointer represents a pointer. Let’s look at the example of Pointer first. The first is the native code:

void* returnPointerArgument(void *arg) {
  return arg;
}

void* returnPointerArrayElement(void* args[], int which) {
  return args[which];
}
Copy after login

The next is the JAVA mapping:

Pointer returnPointerArgument(Pointer p);
Pointer returnPointerArrayElement(Pointer[] args, int which);
Copy after login

In addition to the basic Pointer, you can also customize the typed Pointer, which is PointerType. You only need to inherit PointerType, as shown below:

public static class TestPointerType extends PointerType {
            public TestPointerType() { }
            public TestPointerType(Pointer p) { super(p); }
        }
TestPointerType returnPointerArrayElement(TestPointerType[] args, int which);
Copy after login

Look at the string again Array:

char* returnStringArrayElement(char* args[], int which) {
  return args[which];
}
wchar_t* returnWideStringArrayElement(wchar_t* args[], int which) {
  return args[which];
}
Copy after login

The corresponding JAVA mapping is as follows:

String returnStringArrayElement(String[] args, int which);

WString returnWideStringArrayElement(WString[] args, int which);
Copy after login

Corresponding to Buffer, JAVA NIO provides many types of buffers, such as ByteBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer and DoubleBuffer, etc. . Here we take ByteBuffer as an example to see the specific usage.

First look at the native code:

int32_t fillInt8Buffer(int8_t *buf, int len, char value) {
  int i;

  for (i=0;i < len;i++) {
    buf[i] = value;
  }
  return len;
}
Copy after login

The buffer is filled here. Obviously, this buffer needs to be used later, so here It is not appropriate to use an array. We can choose to use ByteBuffer:

int fillInt8Buffer(ByteBuffer buf, int len, byte value);
Copy after login

and then see how to use it:

TestLibrary lib = Native.load("testlib", TestLibrary.class);

        ByteBuffer buf  = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder());
        final byte MAGIC = (byte)0xED;
        lib.fillInt8Buffer(buf, 1024, MAGIC);
        for (int i=0;i < buf.capacity();i++) {
            assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
        }
Copy after login

Variable parameters

For native and JAVA itself , all support variable parameters. Let’s take an example. In the native method:

int32_t addVarArgs(const char *fmt, ...) {
  va_list ap;
  int32_t sum = 0;
  va_start(ap, fmt);

  while (*fmt) {
    switch (*fmt++) {
    case &#39;d&#39;:
      sum += va_arg(ap, int32_t);
      break;
    case &#39;l&#39;:
      sum += (int) va_arg(ap, int64_t);
      break;
    case &#39;s&#39;: // short (promoted to &#39;int&#39; when passed through &#39;...&#39;) 
    case &#39;c&#39;: // byte/char (promoted to &#39;int&#39; when passed through &#39;...&#39;)
      sum += (int) va_arg(ap, int);
      break;
    case &#39;f&#39;: // float (promoted to ‘double&#39; when passed through ‘...&#39;)
    case &#39;g&#39;: // double
      sum += (int) va_arg(ap, double);
      break;
    default:
      break;
    }
  }
  va_end(ap);
  return sum;
}
Copy after login

The corresponding JAVA method mapping is as follows:

public int addVarArgs(String fmt, Number... args);
Copy after login

The corresponding calling code is as follows:

int arg1 = 1;
int arg2 = 2;
assertEquals("32-bit integer varargs not added correctly", arg1 + arg2,
                     lib.addVarArgs("dd", arg1, arg2));
Copy after login

The above is the detailed content of Java's JNA type mapping attention to details and usage. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Perfect Number in Java Perfect Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Smith Number in Java Smith Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

Create the Future: Java Programming for Absolute Beginners Create the Future: Java Programming for Absolute Beginners Oct 13, 2024 pm 01:32 PM

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

See all articles