我在调用FindElements类的方法initizlize()时,在线程“main”java.lang.UnsatisfiedLinkError:FindElements.initialize()V中遇到异常。请查看附带的详细信息。 据我所知,可以加载DLL,但是在调用方法时会抛出异常。我已多次手动检查方法签名以确保它们是正确的。
"C:\Program Files\Java\jdk1.8.0_73\bin\java" -Didea.launcher.port=7532 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 14.0\bin" -Dfile.encoding=UTF-8 -classpath "C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\target\classes;C:\Program Files\Java\jdk1.8.0_73\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\rt.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_73\jre\lib\ext\zipfs.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\jna-4.0.0.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\jawin-stubs.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\jawin.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\JNativeHook.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\commons-configuration-1.6.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\jfxrt.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\commons-lang-2.5.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\commons-logging-1.1.1.jar;C:\Users\Mike\Desktop\Summer_Research_2016\Gaze UI Automation\lib\commons-collections-3.2.1.jar;C:\Users\Mike\.m2\repository\com\github\mmarquee\ui-automation\0.3.10\ui-automation-0.3.10.jar;C:\Users\Mike\.m2\repository\net\java\dev\jna\jna\4.3.0\jna-4.3.0.jar;C:\Users\Mike\.m2\repository\net\java\dev\jna\jna-platform\4.3.0\jna-platform-4.3.0.jar;C:\Users\Mike\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\Users\Mike\.m2\repository\org\hamcrest\hamcrest-all\1.3\hamcrest-all-1.3.jar;C:\Users\Mike\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\Mike\.m2\repository\org\mockito\mockito-core\2.0.28-beta\mockito-core-2.0.28-beta.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 14.0\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain testBetaUIFrame
Exception in thread "main" java.lang.UnsatisfiedLinkError: FindElements.initialize()V
at FindElements.initialize(Native Method)
at testBetaUIFrame.main(testBetaUIFrame.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Process finished with exit code 1
调用JNI的Java类:
LibraryConfiguration类将指定的文件夹添加到库路径。
public class FindElements {
public native void initialize();
public native String[] getElements(int type);
public native void invokeElement(int index, int type);
public native void uninitialize();
static {
try {
LibraryConfiguration.addLibraryPath(
LibraryConfiguration.changeFileSeparator("\\libs"));
System.loadLibrary("FindElements");
} catch (Exception e) {
e.printStackTrace();
}
}
}
FindElements.cpp
#include <windows.h>
#include "stdafx.h"
#include <stdio.h>
#include "jni.h"
#include "FindElements.h"
#include <string>
#include <math.h>
#include <vector>
#include "UIAutomationClient.h"
#include "UIAutomation.h"
#pragma comment(lib,"Ole64.lib")
#pragma comment(lib,"User64.lib")
#pragma comment(lib,"OleAut64.lib")
using namespace std;
int BUTTON = 0;
int SPLITBUTTON = 1;
int HYPERLINK = 2;
int TREEITEM = 3;
int TABITEM = 4;
int MENUITEM = 5;
int EDIT = 6;
int LISTITEM = 7;
IUIAutomation *g_pAutomation;
IUIAutomationElement *parent = NULL;
IUIAutomationElementArray *cbuttons = NULL;//0
IUIAutomationElementArray *cSplitButtons = NULL;//1
IUIAutomationElementArray *cHyperLinks = NULL;//2
IUIAutomationElementArray *cTreeItems = NULL;//3
IUIAutomationElementArray *cTabItems = NULL;//4
IUIAutomationElementArray *cMenuItems = NULL;//5
IUIAutomationElementArray *cEdit = NULL;//6
IUIAutomationElementArray *cListItem = NULL;//7
unsigned int DISTANCE = 75;
string& BstrToStdString(const BSTR bstr, string& dst, int cp = CP_UTF8)
{
......
}
// conversion with temp.
string BstrToStdString(BSTR bstr, int cp = CP_UTF8)
{
string str;
BstrToStdString(bstr, str, cp);
return str;
}
extern "C" {
IUIAutomationElementArray* GetElements(IUIAutomationElement* pParent, VARIANT varProp)
{
if (pParent == NULL)
{
return NULL;
}
IUIAutomationCondition* pCondition = NULL;
IUIAutomationCondition* pEnabledCondition = NULL;
IUIAutomationCondition* pCombinedCondition = NULL;
IUIAutomationElementArray* pFound = NULL;
g_pAutomation->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &pCondition);
if (pCondition == NULL)
goto cleanup;
// Create a property condition for the enabled property.
varProp.vt = VT_BOOL;
varProp.boolVal = VARIANT_TRUE;
g_pAutomation->CreatePropertyCondition(UIA_IsEnabledPropertyId, varProp, &pEnabledCondition);
if (pEnabledCondition == NULL)
goto cleanup;
// Combine the conditions.
g_pAutomation->CreateAndCondition(pCondition, pEnabledCondition, &pCombinedCondition);
if (pCombinedCondition == NULL)
goto cleanup;
// Find the matching elements. Note that if the scope is changed to TreeScope_Descendants,
// system buttons on the caption bar will be found as well.
pParent->FindAll(TreeScope_Descendants, pCombinedCondition, &pFound);
cleanup:
if (pCondition != NULL)
pCondition->Release();
......
return pFound;
}
IUIAutomationElement* GetContainingWindow(IUIAutomationElement* pChild)
{
if (pChild == NULL)
return NULL;
IUIAutomationElement* pDesktop = NULL;
HRESULT hr = g_pAutomation->GetRootElement(&pDesktop);
if (FAILED(hr))
return NULL;
BOOL same;
g_pAutomation->CompareElements(pChild, pDesktop, &same);
if (same)
{
pDesktop->Release();
return NULL; // No parent, so return NULL.
}
IUIAutomationElement* pParent = NULL;
IUIAutomationElement* pNode = pChild;
// Create the treewalker.
IUIAutomationTreeWalker* pWalker = NULL;
g_pAutomation->get_ControlViewWalker(&pWalker);
if (pWalker == NULL)
goto cleanup;
// Walk up the tree.
while (TRUE)
{
hr = pWalker->GetParentElement(pNode, &pParent);
if (FAILED(hr) || pParent == NULL)
{
break;
}
g_pAutomation->CompareElements(pParent, pDesktop, &same);
if (same)
{
pDesktop->Release();
pParent->Release();
pWalker->Release();
// Reached desktop, so return next element below it.
return pNode;
}
if (pNode != pChild) // Do not release the in-param.
pNode->Release();
pNode = pParent;
}
cleanup:
if ((pNode != NULL) && (pNode != pChild))
pNode->Release();
......
return NULL;
}
JNIEXPORT void JNICALL Java_FindElements_initialize(JNIEnv *env, jobject obj)
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,
CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation),
(void**)&g_pAutomation);
POINT pt;
GetPhysicalCursorPos(&pt);
IUIAutomationElement *pAtMouse;
hr = g_pAutomation->ElementFromPoint(pt, &pAtMouse);
parent = GetContainingWindow(pAtMouse);
hr = parent->SetFocus();
}
JNIEXPORT jobjectArray JNICALL Java_FindElements_getElements(JNIEnv *env, jobject obj, jint type)
{
jobjectArray objArray;
vector<string> name, index;
vector<string> left, top, right, bottom;
int k = 0;
string str, str1, str2;
HRESULT hr;
if (type == BUTTON)
{......}
objArray = (jobjectArray)env->NewObjectArray(k,
env->FindClass("java/lang/String"),
env->NewStringUTF(""));
for (int i = 0; i < k; i++)
{
string st = index.at(i) + "l" + left.at(i) + "t" + top.at(i) + "r" + right.at(i) + "b" + bottom.at(i) + " " + name.at(i);
const char * n = st.c_str();
env->SetObjectArrayElement(objArray, i, env->NewStringUTF(n));
}
return objArray;
}
JNIEXPORT void JNICALL Java_FindElements_invokeElement(JNIEnv *, jobject, jint index, jint type)
{
IUIAutomationElement *cele = NULL;//used to find the invoke pattern
IUIAutomationInvokePattern *pPattern = NULL;
HRESULT hr;
if (type == BUTTON)
{...... }
cele = NULL;
}
JNIEXPORT void JNICALL Java_FindElements_uninitialize(JNIEnv *env, jobject obj)
{
if (cbuttons != NULL)
{...... }
}
}
FindElements.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class FindElements */
#ifndef _Included_FindElements
#define _Included_FindElements
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: FindElements
* Method: initialize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_FindElements_initialize
(JNIEnv *, jobject);
/*
* Class: FindElements
* Method: getElements
* Signature: (I)[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_FindElements_getElements
(JNIEnv *, jobject, jint);
/*
* Class: FindElements
* Method: invokeElement
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_FindElements_invokeElement
(JNIEnv *, jobject, jint, jint);
/*
* Class: FindElements
* Method: uninitialize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_FindElements_uninitialize
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
来自javah的FindElements.h:
(更新)仍然是同样的错误。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class FindElements */
#ifndef _Included_FindElements
#define _Included_FindElements
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: FindElements
* Method: initialize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_FindElements_initialize
(JNIEnv *, jobject);
/*
* Class: FindElements
* Method: getElements
* Signature: (I)[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_FindElements_getElements
(JNIEnv *, jobject, jint);
/*
* Class: FindElements
* Method: invokeElement
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_FindElements_invokeElement
(JNIEnv *, jobject, jint, jint);
/*
* Class: FindElements
* Method: uninitialize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_FindElements_uninitialize
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
我在Visual Studio中的属性设置中添加了必要DLL的路径。
其他目录C ++ General
其他目录链接器
有人可以提出任何建议吗?
答案 0 :(得分:0)
看起来你的代码中有一些奇怪的东西。
您的标题有以下内容:
JNIEXPORT jboolean JNICALL Java_EyeXJavaWrapper_initialize
(JNIEnv *, jobject);
在你的代码(cpp)中你有
JNIEXPORT void JNICALL Java_FindElements_initialize(JNIEnv *env, jobject obj)
您是否使用javah生成头文件?
javah -jni -cp where_your_class_files_are FindElements
我还建议将FindElements放在包中。你可以在这里找到关于JNI的非常基础的教程:http://jnicookbook.owsiak.org/recipe-No-001/