You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从JVM外部地址获取String?从LongBuffer地址转char*为byte[]可行吗?

Can I copy data from a native char* (addressed via java.nio.LongBuffer) into a Java byte[]?

Absolutely—this is possible, but it requires working with Java's low-level native/unsafe APIs since you're directly interacting with off-heap memory pointers. Let's walk through the options and critical caveats to do this safely:

Key Background First

First, confirm your LongBuffer holds a valid native memory address pointing to a char* within your process. If this address is invalid (e.g., already freed, from another process), any attempt to access it will crash the JVM immediately—so double-check validity before proceeding.

Option 1: Use sun.misc.Unsafe (or JDK 9+ jdk.internal.misc.Unsafe)

This is a quick way to prototype, but note that Unsafe is an internal, unsupported API that may change or be removed in future JDK versions.

Steps to implement:

  • Retrieve the Unsafe instance via reflection (it’s not publicly accessible):
    private static Unsafe getUnsafe() throws Exception {
        Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
        unsafeField.setAccessible(true);
        return (Unsafe) unsafeField.get(null);
    }
    
  • Extract the pointer value from your LongBuffer:
    long charPtr = yourLongBuffer.get(0); // Assuming the address is stored at index 0
    
  • Define the total byte length of your char* data (you need to know this upfront):
    • If your C char is 1-byte (ASCII/UTF-8), total bytes = number of chars
    • If it’s a 2-byte wide character (like Windows wchar_t), total bytes = number of chars × 2
  • Allocate a Java byte[] and copy the native memory into it:
    Unsafe unsafe = getUnsafe();
    int totalBytes = charCount * sizeofChar; // Replace with actual byte count
    byte[] result = new byte[totalBytes];
    // Copy from native pointer to Java byte array
    unsafe.copyMemory(null, charPtr, result, Unsafe.ARRAY_BYTE_BASE_OFFSET, totalBytes);
    

JNI is the official, supported way to interact with native code, making it more stable and maintainable for production use.

Steps to implement:

  1. Declare a native method in your Java class:
    public class NativeMemoryCopier {
        // Load the compiled native library (.so for Linux, .dll for Windows)
        static {
            System.loadLibrary("NativeCopier");
        }
    
        /**
         * Copies data from a native char* to a Java byte[]
         * @param ptr Address of the native char*
         * @param charCount Number of char elements to copy
         * @param dest Target byte array (must be large enough to hold all bytes)
         */
        private native void copyCharPtrToByteArray(long ptr, int charCount, byte[] dest);
    }
    
  2. Write the corresponding C implementation:
    #include <jni.h>
    #include <string.h>
    
    JNIEXPORT void JNICALL Java_NativeMemoryCopier_copyCharPtrToByteArray(
        JNIEnv *env, jobject obj, jlong ptr, jint charCount, jbyteArray dest) {
        // Cast the long pointer to a native char*
        char* nativeCharPtr = (char*)ptr;
        // Get a direct pointer to the Java byte array
        jbyte* destBytes = (*env)->GetByteArrayElements(env, dest, NULL);
        if (destBytes == NULL) {
            return; // Handle memory allocation failure
        }
        // Copy the data: adjust sizeof(char) if using wide chars (e.g., wchar_t)
        memcpy(destBytes, nativeCharPtr, charCount * sizeof(char));
        // Release the byte array back to the JVM
        (*env)->ReleaseByteArrayElements(env, dest, destBytes, 0);
    }
    
  3. Compile the C code into a native library and call the method from Java.

Critical Caveats to Avoid Disaster

  • Pointer Validity: Never access a pointer that's been freed, points to memory outside your process, or is uninitialized—this will crash the JVM instantly.
  • Character Encoding: C's char is ambiguous: it can be 1-byte (ASCII/UTF-8) or 2-byte (wide chars). You must know the exact encoding/byte size of the native data to avoid garbage in your byte[].
  • Byte Order: If working with wide chars, note that native systems often use little-endian byte order, while Java uses big-endian. You may need to swap bytes if the data is UTF-16.
  • Memory Management: If you allocated the native char* yourself, ensure you have a native method to free that memory to avoid leaks.
  • Unsafe Risks: Unsafe bypasses Java's memory safety guarantees—any mistake here can corrupt memory or crash the JVM. Stick to JNI for production systems.

内容的提问来源于stack exchange,提问作者Monseigneur Artous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:08