我有一個文件寫成如下:加載JNI的Dll
package JNI;
public class Natives {
public static final int PAGE_READONLY = 0x02;
public static final int PAGE_READWRITE = 0x04;
public static final int PAGE_WRITECOPY = 0x08;
public static final int FILE_MAP_COPY = 0x0001;
public static final int FILE_MAP_WRITE = 0x0002;
public static final int FILE_MAP_READ = 0x0004;
public static native long createFileMapping(long hFile, int lpAttributes, int dwMaximumSizeHigh, int dwMaximumSizeLow, String lpName);
public static native long openFileMapping(int dwDesiredAccess, boolean bInheritHandle, String lpName);
public static native long mapViewOfFile(long hFileMap, int dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, int dwNumberOfBytesToMap);
public static native long unmapViewOfFile(long hFileMap);
public static native long closeHandle(long hFile);
}
然後我用生成JNI文件JAVAH:
extern "C" JNIEXPORT jlong JNICALL Java_JNI_Natives_createFileMapping(JNIEnv *env, jclass, jlong hFile, jint lpProtect, jint dwMaximumSizeHigh, jint dwMaximumSizeLow, jstring lpName)
{
HANDLE hFileMap = nullptr;
LPCSTR Name = env->GetStringUTFChars(lpName, nullptr);
if ((hFileMap = CreateFileMapping(hFile == -1 ? INVALID_HANDLE_VALUE : reinterpret_cast<HANDLE>(hFile), nullptr, lpProtect, dwMaximumSizeHigh, dwMaximumSizeLow, Name)) != nullptr)
{
if (errno == ERROR_ALREADY_EXISTS)
{
CloseHandle(hFileMap);
}
}
env->ReleaseStringUTFChars(lpName, Name);
return reinterpret_cast<jlong>(hFileMap);
}
extern "C" JNIEXPORT jlong JNICALL Java_JNI_Natives_openFileMapping(JNIEnv *env, jclass, jint dwDesiredAccess, jboolean bInheritHandle, jstring lpName)
{
LPCSTR Name = env->GetStringUTFChars(lpName, nullptr);
HANDLE hFileMap = OpenFileMapping(dwDesiredAccess, static_cast<bool>(bInheritHandle), Name);
env->ReleaseStringUTFChars(lpName, Name);
return reinterpret_cast<jlong>(hFileMap);
}
extern "C" JNIEXPORT jlong JNICALL Java_JNI_Natives_mapViewOfFile(JNIEnv *, jclass, jlong hFileMap, jint dwDesiredAccess, jint dwFileOffsetHigh, jint dwFileOffsetLow, jint dwNumberOfBytesToMap)
{
void* pData = MapViewOfFile(reinterpret_cast<HANDLE>(hFileMap), dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap);
return reinterpret_cast<jlong>(pData);
}
extern "C" JNIEXPORT jlong JNICALL Java_JNI_Natives_unmapViewOfFile(JNIEnv *, jclass, jlong hFileMap)
{
return reinterpret_cast<jboolean>(static_cast<uint8_t>(UnmapViewOfFile(reinterpret_cast<void*>(hFileMap))));
}
extern "C" JNIEXPORT jlong JNICALL Java_JNI_Natives_closeHandle(JNIEnv *, jclass, jlong hFile)
{
return reinterpret_cast<jboolean>(static_cast<uint8_t>(CloseHandle(reinterpret_cast<HANDLE>(hFile))));
}
但只要加載DLL和我打電話的功能等所以:
long Handle = Natives.createFileMapping(-1,Natives.FILE_MAP_READ | Natives.FILE_MAP_WRITE,500,0,「NativeDLL」); debug(Handle);
它打印:
運行:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000061288f69, pid=4692, tid=844
#
# JRE version: 7.0_21-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.21-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# V [jvm.dll+0x38f69]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\Brandon\Documents\NetBeansProjects\Smart\hs_err_pid4692.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#
Java Result: 1
任何想法,我做錯了什麼?
:S GetStringUTFChars返回一個const char *,CreateFileMapping將其作爲最後一個參數。我喜歡你的答案,但我仍然遇到與unicode轉換有關的問題。 – Brandon 2013-05-10 19:41:01
@CantChooseUsernames每個字符串都是來自特定字符集的編碼字符序列。 'CreateFileMapping'是'CreateFileMappingA'或'CreateFileMappingW'的別名。第一個需要使用當前ANSI代碼頁編碼的字符串。第二個需要使用UTF-16LE編碼的字符串。所以,我再說一次,_no版本的'CreateFileMapping'接受'GetStringUTFChars'_返回的UTF-8字符串。指針類型並不重要。它僅表示編碼的最小元素,但沒有提及編碼或字符集。 – 2013-07-23 23:33:48
我使用上面相同的代碼解決了它。我只需要改變調用約定並使用.def文件導出。代碼也可以工作。 – Brandon 2013-07-24 17:20:45