スレッド "main"で例外が発生しましたjava.lang.UnsatisfiedLinkError:メソッドinitizlizeを呼び出すときにFindElements.initialize()V )のFindElementsクラスです。付属の詳細をご覧ください。 私が理解できる限り、DLLはロードできますが、メソッドが呼び出されると例外がスローされます。私は手動でメソッドの署名を数回チェックして、それらが正しいことを確認しました。スレッド "main"の例外java.lang.UnsatisfiedLinkError JavaからC++ 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
JavaクラスはJNIを呼び出す:
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 javahはから
/* 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
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++一般
追加のディレクトリリンカ
は誰かの提案を提案することはできますか?
こんにちは、mko、申し訳ありませんが間違ったヘッダーファイルをアップロードしました。 –
これはプロジェクトからのもので、ヘッダファイルを自分で生成しませんでした。以前は32ビットJVMで動作していましたが、今は64ビットに再コンパイルしようとしています。 –
私は今、javahを試みます。 –