You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何基于JNI实现Java调用C++获取Windows当前用户名?

嘿,我来帮你把已有的JNI Hello World和Windows用户名获取代码整合起来,完成这个PoC。下面是完整的实现步骤和代码,跟着走就能轻松搞定:

1. 编写Java Native接口类

先创建一个Java类,声明我们需要的native方法,同时负责加载后续编译的动态链接库:

public class WindowsUsername {
    // 声明native方法,用于获取Windows用户名
    public native String getWindowsUsername();

    // 加载动态链接库
    static {
        System.loadLibrary("WindowsUsernameImpl");
    }

    // 测试主函数
    public static void main(String[] args) {
        WindowsUsername usernameGetter = new WindowsUsername();
        String username = usernameGetter.getWindowsUsername();
        System.out.println("当前Windows用户名:" + username);
    }
}
2. 生成JNI头文件

用Java的javac命令生成对应的JNI头文件。打开命令行,进入Java类所在目录,执行:

javac -h . WindowsUsername.java

执行后会生成一个名为WindowsUsername.h的头文件,内容大概是这样的:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class WindowsUsername */

#ifndef _Included_WindowsUsername
#define _Included_WindowsUsername
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     WindowsUsername
 * Method:    getWindowsUsername
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_WindowsUsername_getWindowsUsername
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
3. 实现C++ Native方法

现在把你那部分获取用户名的C++代码和JNI的实现结合起来,创建一个WindowsUsernameImpl.cpp文件:

#include "WindowsUsername.h"
#include <windows.h>
#include <string>

JNIEXPORT jstring JNICALL Java_WindowsUsername_getWindowsUsername
(JNIEnv* env, jobject obj) {
    // 定义缓冲区,Windows用户名最长不超过256字符(含终止符)
    WCHAR usernameBuffer[256];
    DWORD bufferSize = sizeof(usernameBuffer) / sizeof(WCHAR);

    // 调用Windows API获取用户名
    if (GetUserNameW(usernameBuffer, &bufferSize)) {
        // 将宽字符串转换为JNI的jstring
        return env->NewString(usernameBuffer, wcslen(usernameBuffer));
    } else {
        // 如果获取失败,返回错误信息
        return env->NewStringUTF("获取用户名失败");
    }
}

这里用了GetUserNameW(宽字符版本),因为JNI的字符串处理默认是Unicode编码,这样能更好地支持包含中文、特殊字符的用户名,避免乱码问题。

4. 编译C++代码为DLL

接下来需要把C++代码编译成Windows动态链接库(.dll文件)。如果你用的是Visual Studio的编译器(cl.exe),可以执行以下命令:

cl /LD /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32" WindowsUsernameImpl.cpp
  • /LD 参数表示编译为动态链接库
  • /I 参数指定JNI头文件的路径,%JAVA_HOME% 是你的Java安装目录,比如C:\Program Files\Java\jdk1.8.0_301

编译成功后会生成WindowsUsernameImpl.dll文件。

5. 运行Java程序

最后运行Java程序,确保DLL文件和Java类在同一个目录,或者通过-Djava.library.path指定DLL的路径:

java -Djava.library.path=. WindowsUsername

正常情况下,你会看到输出当前登录的Windows用户名。

一些关键注意事项
  • 确保编译C++代码时的位数(32位/64位)和你的Java版本完全一致,否则会出现加载库失败的错误
  • JNI函数名必须和头文件里生成的完全一致,哪怕一个下划线错了,Java都找不到对应的native方法
  • 如果你用的是MinGW编译器,编译命令会略有不同,比如:g++ -shared -o WindowsUsernameImpl.dll -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" WindowsUsernameImpl.cpp

内容的提问来源于stack exchange,提问作者Arka Mallick

火山引擎 最新活动