2010-03-05 3 views
32

Java 프로그램에서 some methods in Wininet.dll으로 전화해야합니다.Java에서 Win32 API 메소드 호출

자바에서 만드는 새 DLL을 호출하는 방법에 대한 자습서를 많이 찾을 수 있지만 Java에서 이미 존재하는 DLL을 호출하는 방법에 대한 자습서를 찾지 못하는 것 같습니다.

나는 이것이 JNI와 관련되어 있음을 알고 있지만, 정확히 어떻게 이것을합니까? Wininet.h에서 javah으로 전화해야합니까? Wininet.h의 복사본은 어디서 구할 수 있습니까? 기존 자습서에 대한 포인터로 충분합니다.

답변

38
  1. JNA 당신이 원하는 것을 the industry standard 보인다 "Java 프로그램을 기본 공유 라이브러리에 쉽게 액세스 할 수 있습니다 (Windows의 DLL을)없이 FO 확인하는 경우 example usage
    - 자바 코드없는 JNI 또는 네이티브 코드 만 작성 아무것도

  2. Java Foreign Function Interface있다 "필요 R 당신이, 당신이 JRuby 통역을 embedjruby-ffi 느릅 나무입니다 훨씬 더 쉽게를 통해 WINAPI 부를 수있는, here, herehere

+2

이 필요 범프 - JNA는 네이티브 라이브러리 액세스를 위해 순수한 JNI보다 훨씬 뛰어납니다. –

+0

+1 : JNA가 좋은 선택입니다. 자바에서 함수 서명을 매핑하는 방법을 알아야하지만, 최근에 JNA를 사용하여 블루투스 장치를 통해 네이티브 Win32 API. – wierob

+0

JNA 정말 매끄 럽다. 내가 다른 한 주일에 직장에서 친구에게 설명 할 때, 나는 실제로 그에게 "마술"이라고 말할만큼 멀리 갔다. – rob

3

네이티브 라이브러리를 직접 호출 할 수 없습니다. 이는 메소드의 일부 인수가 Java Native Interface에서 지원되지 않기 때문입니다.

GlueGen이라는 것이 있습니다. 이것은 네이티브 DLL에 동적으로 링크되는 별도의 바이너리를 생성합니다. 생성 된 바이너리는 JNI와 호환되므로 Java에서 호출 할 수 있습니다.

http://en.wikipedia.org/wiki/Gluegen

당신은 아마 플랫폼 SDK (또는 Windows SDK, 최신 버전)이 필요합니다, Wininet.dll을위한 헤더 파일을 얻으려면. 이 헤더 파일을 포함하는 온라인 저장소를 인터넷에서 검색 할 수도 있습니다.

GlueGen는 헤더 파일, ANSI C 컴파일러 등

GlueGen을 필요로하지 않습니다 NativeCall라는 덜 알려진 라이브러리가 있는데,이 필요합니다. 이미 Java와 호환되는 바이너리가 있습니다. 이것은 자바로부터의 요청에 따라 DLL을 동적으로로드 할 것이므로 분명히 느리다. 나는이 사용하지 않은, 그러나, 그러나 유망한 소리 :

http://johannburkard.de/software/nativecall/

12

내가 조금 전에이 작업을 수행했다 참조하십시오. C 컴파일러와 Windows 헤더 파일이 필요합니다. 그것이 무료이기 때문에 나는 mingw를 사용했고 나는 하나의 작은 파일만을 컴파일하고 있었다.

먼저 수업을 들으십시오.

package org.whatever.thingy; 

public class MyClass { 
    // Here is a JNI method, identified by 'native' 

    public static native callWin32Thingy(int x, int y, boolean z); 

    /* At this point, normal class stuff, other methods, variables, whatever */ 
} 

당신은 자동으로 클래스를 가지고 .H 및 .c 인 파일을 생성합니다 JDK에서 제공되는 명령 중 하나를 사용하는 예를 들면 다음과 같습니다. 명령은 "javah"입니다. .c 파일에서

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy 
    (JNIEnv *, jclass, jint, jint, jboolean); 

, 당신은 당신이 필요로하는 어떤 창 헤더 포함 및 방법을 구체화 : 메소드 서명은 다음과 같이 보일 것입니다.

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy 
    (JNIEnv *a, jclass b, jint c, jint d, jboolean e) { 
    // Prep steps.... 

    Win32MethodCallWeCareAbout(x, y, z, hWhatever); 

    // Cleanup stuff... 
} 

그것은 당신이 방법을 이름을 변경하지 않는 매우 중요 입니다, 그게이 특정 클래스와 연관되는 방식입니다.

일단이 파일을 얻으면 해당 파일을 DLL로 컴파일합니다. mingw에 사용 된 명령은 다음과 같습니다. 클래스/경로/등을 조정해야합니다.

c:/MinGW/bin/gcc -c -Ic:/MinGW/include -I"c:/Program Files/Java/jdk1.5.0_12/include" 
    -I"c:/Program Files/Java/jdk1.5.0_12/include/win32" -D__int64="long long" 
    com_whatever_thingy_MyClass_JNIHelper.c 

c:/MinGW/bin/gcc -shared -o JNIHelper.dll 
    com_whatever_thingy_MyClass_JNIHelper_JNIHelper.o 
    -Wl,--add-stdcall-alias,--kill-at,--output-def,def_file 

이렇게하면 내 DLL 이름이 JNIHelper.dll 인 일부 파일이 생성됩니다.

이 시점에서 기본적으로 완료됩니다. Java 클래스를 정상적으로 사용하면 정적 메서드를 호출 할 때 Win32 코드가 실행됩니다. 라이브러리를 가져 오기 만하면됩니다. 이것은 "JNIHelper.dll"라는 이름의 라이브러리를로드하고 코드로 연결하기 위해 자바의 원인이됩니다

System.loadLibrary("JNIHelper"); 

: 어딘가에 코드에서이 라인이 필요합니다 (내 클래스의 정적 블록에 넣어) . Java가 알고있는 라이브러리 경로의 어딘가에 있어야합니다.

그게 전부입니다. 상용구가 많지만 간단한 포장을하는 경우 쉽습니다. Java 유형을 처리하거나 메모리를 할당해야하는 경우 악화됩니다 (참고 : 필요하지 않기 때문에 경험이 없습니다).

는 괜찮은 모습 전체 튜토리얼 here (첫번째 내가 찾은 오늘있다, 당신은 웹에서 다른 사람을 찾을 수 있습니다. JNI에 Wikipedia 기사가 너무 더 많은 정보를 가지고있다.

희망이 도움이됩니다.

+1

Java 클래스에 "기본"키워드가 필요하지 않습니까? –

+0

@ Thorbjørn : 네 권리, 나는 그것을 놓쳤다, 고마워. 추가로 수정되었습니다. – MBCook