Java 构建HashMap<;字符串,字符串[]>;通过JNI

Java 构建HashMap<;字符串,字符串[]>;通过JNI,java,c++,hashmap,java-native-interface,Java,C++,Hashmap,Java Native Interface,我有一个Java类调用本机方法ACLInfo(stringpath),这个本机方法应该返回HashMap以在Java中使用。下面是java代码 import java.util.*; public class test { native Map<String, String[]> ACLInfo(String s); static { System.loadLibrary("test"); } static p

我有一个Java类调用本机方法ACLInfo(stringpath),这个本机方法应该返回HashMap以在Java中使用。下面是java代码

import java.util.*;

public class test
{
  native Map<String, String[]> ACLInfo(String s);
  
   static
   {
      System.loadLibrary("test");
   }
  
   static public void main(String args[])
   {
   
      test obj = new test();
      Map<String, String[]> map = obj.ACLInfo("C:/Windows/Boot/Resources/bootres.dll");

      for (Map.Entry<String, String[]> entry : map.entrySet())
      {
          String name = entry.getKey();
          System.out.println("Name:"+name);
          System.out.println("Properties are:");
          for(String text : entry.getValue())
          {
              if(text.equals("Full Control")){
                 System.out.println(text);
                 continue;
             }
              if(text.equals("Read"))
                 System.out.println(text);
             if(text.equals("Write"))
                 System.out.println(text);
             if(text.equals("Execute"))
                 System.out.println(text);
          }
          
      }
   }
}
import java.util.*;
公开课考试
{
本机映射ACLInfo(字符串s);
静止的
{
系统加载库(“测试”);
}
静态公共void main(字符串参数[])
{
测试对象=新测试();
Map Map=obj.ACLInfo(“C:/Windows/Boot/Resources/bootres.dll”);
对于(Map.Entry:Map.entrySet())
{
字符串名称=entry.getKey();
System.out.println(“名称:”+Name);
System.out.println(“属性为:”);
for(字符串文本:entry.getValue())
{
if(text.equals(“完全控制”)){
System.out.println(文本);
继续;
}
if(text.equals(“Read”))
System.out.println(文本);
if(text.equals(“Write”))
System.out.println(文本);
if(text.equals(“执行”))
System.out.println(文本);
}
}
}
}
本机代码是

#include <iostream>
#include <jni.h>
#include <string.h>
#include <windows.h>
#include <tchar.h>
#include <Lmcons.h>
#include "test.h"
#include "accctrl.h"
#include "aclapi.h"

using namespace std;

JNIEXPORT jobject JNICALL Java_test_ACLInfo(JNIEnv *env, jobject jobj, jstring s)
{
    jobjectArray ret;
    jstring jstr;
    PSID pSidOwner = NULL;
    BOOL bRtnBool = TRUE;
    DWORD dwRtnCode = 0;
    SID_NAME_USE eUse = SidTypeUnknown;
    HANDLE hFile;
    PSECURITY_DESCRIPTOR pSD = NULL;
    PACL pOldDACL = NULL;
    int i,aceNum;
    const char* test;
    std::string name,reslt;

    const char* nativeString = env->GetStringUTFChars(s, 0);
    LPCSTR file = nativeString;
    // Get the handle of the file object.
    hFile = CreateFile(
                  file,
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);


    // Get the SID of the file.
    dwRtnCode = GetSecurityInfo(
                  hFile,
                  SE_FILE_OBJECT,
                  DACL_SECURITY_INFORMATION,
                  &pSidOwner,
                  NULL,
                  &pOldDACL,
                  NULL,
                  &pSD);

    PACL pAcl = pOldDACL;
    aceNum = pOldDACL->AceCount;

    ret = (jobjectArray)env->NewObjectArray(3, env->FindClass("java/lang/String"), env->NewStringUTF(""));

    jclass mapClass = env->FindClass("java/util/HashMap");      //HashMap class in java library
    if(mapClass == NULL)
    {
        return NULL;
    }
    jsize map_len = aceNum;
    jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");  //constructor of HashMap class
    jobject hashMap = env->NewObject(mapClass, init, map_len);      //creating a new object for that class
    jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;");

    for (i = 0; i < aceNum; i++)
    {
    PACCESS_ALLOWED_ACE AceItem;
    ACE_HEADER *aceAddr = NULL;
    if (GetAce(pOldDACL, i, (LPVOID*)&AceItem) && GetAce(pOldDACL, i, (LPVOID*)&aceAddr))
        {
        LPTSTR AccountBuff = NULL, DomainBuff = NULL;
        DWORD AccountBufflength = 1, DomainBufflength = 1;
        PSID_NAME_USE peUse = new SID_NAME_USE;
        PSID Sid = &AceItem->SidStart;
        LookupAccountSid(NULL, Sid, AccountBuff, (LPDWORD)&AccountBufflength, DomainBuff, (LPDWORD)&DomainBufflength, peUse);

        AccountBuff = (LPSTR)malloc(AccountBufflength * sizeof(LPSTR));
        DomainBuff = (LPSTR)malloc(DomainBufflength * sizeof(LPSTR));

        LookupAccountSid(NULL, Sid, AccountBuff, &AccountBufflength, DomainBuff, &DomainBufflength, peUse);

        std::string acc=AccountBuff;
        std::string dom=DomainBuff;
        name = acc+"\\"+dom;

        ACCESS_MASK Mask = AceItem->Mask;
        if (((Mask & GENERIC_ALL) == GENERIC_ALL) || ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS)){
         reslt="Full Control";
         test = reslt.c_str();
         env->SetObjectArrayElement(ret,i,env->NewStringUTF(test));
         env->CallObjectMethod(hashMap, put, env->NewStringUTF(name.c_str()), ret);
         continue;
        }
         int j=0;
        if (((Mask & GENERIC_READ) == GENERIC_READ) || ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ))
            {
                reslt="Read";
                test = reslt.c_str();
                env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
            }
        if (((Mask & GENERIC_WRITE) == GENERIC_WRITE) || ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE))
            {
                reslt="Write";
                test = reslt.c_str();
                env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
            }
        if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE) || ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE))
            {
                reslt="Execute";
                test = reslt.c_str();
                env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
            }
        env->CallObjectMethod(hashMap, put, env->NewStringUTF(name.c_str()), ret);
        }
    }
    return hashMap;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括“test.h”
#包括“accctrl.h”
#包括“aclapi.h”
使用名称空间std;
JNIEXPORT jobject JNICALL Java_test_ACLInfo(JNIEnv*env、jobject jobj、jstring s)
{
jobject数组ret;
jstring-jstr;
PSID pSidOwner=NULL;
BOOL bRtnBool=TRUE;
DWORD dwRtnCode=0;
SID_NAME_USE eUse=SidTypeUnknown;
处理文件;
PSECURITY_描述符pSD=NULL;
PACL pOldDACL=NULL;
inti,aceNum;
常量字符*测试;
std::字符串名称,reslt;
const char*nativeString=env->GetStringUTFChars(s,0);
LPCSTR文件=nativeString;
//获取文件对象的句柄。
hFile=CreateFile(
文件
泛读,
文件共享读取,
无效的
开放式,
文件\u属性\u正常,
无效);
//获取文件的SID。
dwRtnCode=GetSecurityInfo(
hFile,
SE_文件_对象,
DACL_安全信息,
&普西唐纳,
无效的
&波尔达克尔,
无效的
&pSD);
PACL-PACL=pOldDACL;
aceNum=pOldDACL->acecont;
ret=(jobjectArray)env->NewObjectArray(3,env->FindClass(“java/lang/String”),env->NewStringUTF(“”);
jclass mapClass=env->FindClass(“java/util/HashMap”);//java库中的HashMap类
if(mapClass==NULL)
{
返回NULL;
}
jsize map_len=aceNum;
jmethodID init=env->GetMethodID(mapClass,”,“(I)V”);//HashMap类的构造函数
jobject hashMap=env->NewObject(mapClass、init、map_len);//为该类创建新对象
jmethodID put=env->GetMethodID(mapClass,“put”,“(Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;”;
对于(i=0;iSidStart;
LookupAccountSid(NULL,Sid,AccountBuff,(LPDWORD)和AccountBufflength,DomainBuff,(LPDWORD)和DomainBufflength,peUse);
AccountBuff=(LPSTR)malloc(AccountBufflength*sizeof(LPSTR));
DomainBuff=(LPSTR)malloc(DomainBufflength*sizeof(LPSTR));
LookupAccountSid(NULL、Sid、AccountBuff和AccountBufflength、DomainBuff和DomainBufflength、peUse);
std::string acc=AccountBuff;
std::string dom=DomainBuff;
名称=acc+“\\”+dom;
访问\u MASK MASK=AceItem->MASK;
if((屏蔽和通用访问)=通用访问)((屏蔽和文件访问)=文件访问)){
reslt=“完全控制”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,i,env->NewStringUTF(test));
env->CallObjectMethod(hashMap,put,env->NewStringUTF(name.c_str()),ret);
继续;
}
int j=0;
如果((屏蔽和通用读取)=通用读取);(屏蔽和文件通用读取)=文件通用读取))
{
reslt=“读取”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
if(((掩码和通用写入)=通用写入)((掩码和文件通用写入)=文件通用写入))
{
reslt=“写入”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
if(((掩码和泛型执行)=泛型执行)| |((掩码和文件泛型执行)=文件泛型执行))
{
reslt=“执行”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
env->CallObjectMethod(hashMap,put,env->NewStringUTF(name.c_str()),ret);
}
}
返回hashMap;
}
在运行这个java类时,它显示:java运行时环境检测到一个致命错误:pc=0x000000006d6cd4ed、pid=19504、tid=0x0000000000003da0处的异常访问违反(0xc0000005)

有什么问题吗?
我利用这篇stackoverflow帖子创建hashmap

我重写了您的代码,以消除最严重的bug:

  • 您对
    HashMap\put
    的签名错误
  • 您必须为放入hashmap中的每个元素创建一个
    string[]
    。如果重用同一对象,您将获得相同
    string[]
    的N个副本
  • 无法创建数组o
    JNIEXPORT jobject JNICALL Java_test_ACLInfo(JNIEnv *env, jobject jobj, jstring s)
    {
    
        // removed stuff
        jclass mapClass = env->FindClass("java/util/HashMap");      //HashMap class in java library
        jclass stringClass = env->FindClass("java/lang/String");
        if(mapClass == NULL)
        {
            return NULL;
        }
        jsize map_len = aceNum;
        jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V");  //constructor of HashMap class
        jobject hashMap = env->NewObject(mapClass, init, map_len);      //creating a new object for that class
        jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    
        for (i = 0; i < aceNum; i++) {
            // removed stuff
    
            PACCESS_ALLOWED_ACE AceItem;
            ACE_HEADER *aceAddr = NULL;
            if (GetAce(pOldDACL, i, (LPVOID*)&AceItem) && GetAce(pOldDACL, i, (LPVOID*)&aceAddr)) {
                // removed more stuff
                std::string name = std::string(AccountBuff)+"\\"+std::string(DomainBuff);
                std::vector<std::string> perms;
    
                ACCESS_MASK Mask = AceItem->Mask;
                if (((Mask & GENERIC_ALL) == GENERIC_ALL) || ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS)) {
                    perms.emplace_back("Full Control");
                } else {
                    if (((Mask & GENERIC_READ) == GENERIC_READ) || ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ)) {
                        perms.emplace_back("Read");
                    }
                    if (((Mask & GENERIC_WRITE) == GENERIC_WRITE) || ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE)) {
                        perms.emplace_back("Write");
                    }
                    if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE) || ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE)) {
                        perms.emplace_back("Execute");
                    }
                }
    
                env->PushLocalFrame(10);
                jobject ret = env->NewObjectArray(perms.size(), stringClass, nullptr);
                for (int i = 0; i < perms.size(); i++) {
                    env->SetObjectArrayElement(ret, i, env->NewStringUTF(perms[i].c_str()));
                }
                env->CallObjectMethod(hashMap, put, env->NewStringUTF(name.c_str()), ret);
                env->PopLocalFrame(nullptr);
            }
        }
        return hashMap;
    }