JNA简单函数调用适用于linux(x64)但不适用于Windows(x86)

时间:2011-05-02 10:40:36

标签: c windows linux mapping jna

我正在尝试使用JNA从Java运行以下C函数,但是我在x86窗口(DLL)上遇到错误(无效内存访问)但在x64 linux(.SO)中没有。

c函数

char* testcopy(char* out,char* in)
{
    strcpy(out,in);
    free(in);
    return out;
};

C测试:适用于两个平台(Eclipse CDT / MVC ++)

当函数通过linux共享库或windows dll公开并直接在C中调用时,结果没问题。

...
char out[10];
char* res;
char* in = (char*)malloc(3*sizeof(char)); 
strcpy(in,"ab");
res = testcopy(out,in);
fprintf(stdout,"out: %s\n",out);
fprintf(stdout,"res: %s\n",res);
return 0;

或者使用DLL:

...
HINSTANCE hInst = LoadLibrary(_T("C:\\jnatest.dll")); 
if( hInst != NULL )
{
        typedef char* (*maFonction)(char*, char*);
        char out[10];
        char* res;
        maFonction f;
        char* in = (char*)malloc(3*sizeof(char)); 
        strcpy(in,"ab");

        f = (maFonction) GetProcAddress(hInst, "testcopy"); 
        res = f(out,in);
        fprintf(stdout,"out: %s\n",out);
        fprintf(stdout,"res: %s\n",res);

        FreeLibrary( hInst );
}

JNA出现问题。

public interface IJnaTest extends Library { 
    public Pointer testcopy(PointerByReference out, String in)  throws LastErrorException;
}

Java测试:仅适用于linux64

...
IJnaTest demo = (IJnaTest) Native.loadLibrary(libName, IJnaTest.class);
PointerByReference out = new PointerByReference();
String in ="test";
Pointer ret1 = demo.testcopy(out, in);
System.out.println("ret="+ret1.getString(0));
System.out.println("in="+in.toString());
System.out.println("out="+out.getPointer().getString(0));
...

Windows错误

Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Function.invokePointer(Native Method)
at com.sun.jna.Function.invoke(Function.java:365)
at com.sun.jna.Function.invoke(Function.java:276)
at com.sun.jna.Library$Handler.invoke(Library.java:216)
...

Windows崩溃报告

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x102e683e, pid=1576, tid=3552
#
# JRE version: 6.0_24-b07
# Java VM: Java HotSpot(TM) Client VM (19.1-b02 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [MSVCR100D.dll+0xe683e]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  T H R E A D  ---------------

Current thread (0x003a6400):  JavaThread "main" [_thread_in_native, id=3552, stack (0x008c0000,0x00910000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x3fd0069e

Registers:
EAX=0x3fd0069e, EBX=0x00000004, ECX=0x7fffffff, EDX=0x7ffffffe
ESP=0x0090a128, EBP=0x0090a45c, ESI=0x0090f680, EDI=0x0090f74c
EIP=0x102e683e, EFLAGS=0x00010206

Register to memory mapping:

EAX=0x3fd0069e
0x3fd0069e is pointing to unknown location

EBX=0x00000004
0x00000004 is pointing to unknown location

ECX=0x7fffffff
0x7fffffff is pointing to unknown location

EDX=0x7ffffffe
0x7ffffffe is pointing to unknown location

ESP=0x0090a128
0x0090a128 is pointing into the stack for thread: 0x003a6400
"main" prio=6 tid=0x003a6400 nid=0xde0 runnable [0x0090f000]
   java.lang.Thread.State: RUNNABLE

EBP=0x0090a45c
0x0090a45c is pointing into the stack for thread: 0x003a6400
"main" prio=6 tid=0x003a6400 nid=0xde0 runnable [0x0090f000]
   java.lang.Thread.State: RUNNABLE

ESI=0x0090f680
0x0090f680 is pointing into the stack for thread: 0x003a6400
"main" prio=6 tid=0x003a6400 nid=0xde0 runnable [0x0090f000]
   java.lang.Thread.State: RUNNABLE

EDI=0x0090f74c
0x0090f74c is pointing into the stack for thread: 0x003a6400
"main" prio=6 tid=0x003a6400 nid=0xde0 runnable [0x0090f000]
   java.lang.Thread.State: RUNNABLE


Top of Stack: (sp=0x0090a128)
0x0090a128:   fefefefe fefefefe fefefefe 7fffffff
0x0090a138:   00000032 0000001f fefefefe 00000007
0x0090a148:   fefefefe 00000008 00000001 fefefefe
0x0090a158:   fefefefe fefefefe fefefefe fefefefe
0x0090a168:   fefefefe fefefefe fefefefe fefefefe
0x0090a178:   fefefefe fefefefe fefefefe fefefefe
0x0090a188:   fefefefe fefefefe fefefefe fefefefe
0x0090a198:   fefefefe fefefefe fefefefe fefefefe 

Instructions: (pc=0x102e683e)
0x102e682e:   89 95 70 fd ff ff 85 c9 74 1e 8b 85 74 fd ff ff
0x102e683e:   0f be 08 85 c9 74 11 8b 95 74 fd ff ff 83 c2 01 


Stack: [0x008c0000,0x00910000],  sp=0x0090a128,  free space=296k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [MSVCR100D.dll+0xe683e]
C  [MSVCR100D.dll+0x6d5d6]
C  [MSVCR100D.dll+0x6db00]
C  [MSVCR100D.dll+0x6dd70]
C  [MSVCR100D.dll+0x11adce]
C  [MSVCR100D.dll+0x120a32]
C  [MSVCR100D.dll+0x1209eb]
C  [MSVCR100D.dll+0x116bcb]
C  [MSVCR100D.dll+0x116970]
C  [MSVCR100D.dll+0x119090]
C  [libatih1211b_x86.dll+0x559da]
C  [libatih1211b_x86.dll+0x597db]
C  [jna2907102074982287093.dll+0xcb77]
C  [jna2907102074982287093.dll+0xc7c2]
C  [jna2907102074982287093.dll+0x4561]
C  [jna2907102074982287093.dll+0x4ec1]
j  com.sun.jna.Function.invokePointer(I[Ljava/lang/Object;)Lcom/sun/jna/Pointer;+0
j  com.sun.jna.Function.invoke([Ljava/lang/Object;Ljava/lang/Class;Z)Ljava/lang/Object;+615
j  com.sun.jna.Function.invoke(Ljava/lang/Class;[Ljava/lang/Object;Ljava/util/Map;)Ljava/lang/Object;+214
j  com.sun.jna.Library$Handler.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;+341
j  $Proxy0.winCopyDest_11(Lcom/sun/jna/ptr/PointerByReference;Ljava/lang/String;)Lcom/sun/jna/Pointer;+20
j  test.JnaTest.testJNA11()V+35
j  test.JnaTest.main([Ljava/lang/String;)V+11
v  ~StubRoutines::call_stub
V  [jvm.dll+0xf0ab9]
V  [jvm.dll+0x1837d1]
V  [jvm.dll+0xf0b3d]
V  [jvm.dll+0xfa0d6]
V  [jvm.dll+0x101cde]
C  [javaw.exe+0x2155]
C  [javaw.exe+0x8614]
C  [kernel32.dll+0xb729]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.sun.jna.Function.invokePointer(I[Ljava/lang/Object;)Lcom/sun/jna/Pointer;+0
j  com.sun.jna.Function.invoke([Ljava/lang/Object;Ljava/lang/Class;Z)Ljava/lang/Object;+615
j  com.sun.jna.Function.invoke(Ljava/lang/Class;[Ljava/lang/Object;Ljava/util/Map;)Ljava/lang/Object;+214
j  com.sun.jna.Library$Handler.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;+341
j  $Proxy0.winCopyDest_11(Lcom/sun/jna/ptr/PointerByReference;Ljava/lang/String;)Lcom/sun/jna/Pointer;+20
j  test.JnaTest.testJNA11()V+35
j  test.JnaTest.main([Ljava/lang/String;)V+11
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x02affc00 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=556, stack(0x02d70000,0x02dc0000)]
  0x02af1400 JavaThread "CompilerThread0" daemon [_thread_blocked, id=3548, stack(0x02d20000,0x02d70000)]
  0x02aef800 JavaThread "Attach Listener" daemon [_thread_blocked, id=244, stack(0x02cd0000,0x02d20000)]
  0x02aee400 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=3792, stack(0x02c80000,0x02cd0000)]
  0x02aeac00 JavaThread "Finalizer" daemon [_thread_blocked, id=2300, stack(0x02c30000,0x02c80000)]
  0x02ae6000 JavaThread "Reference Handler" daemon [_thread_blocked, id=3272, stack(0x02be0000,0x02c30000)]
=>0x003a6400 JavaThread "main" [_thread_in_native, id=3552, stack(0x008c0000,0x00910000)]

Other Threads:
  0x02aaa000 VMThread [stack: 0x02b90000,0x02be0000] [id=2228]
  0x02b01c00 WatcherThread [stack: 0x02dc0000,0x02e10000] [id=4052]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
 def new generation   total 2432K, used 1670K [0x229a0000, 0x22c40000, 0x25440000)
  eden space 2176K,  76% used [0x229a0000, 0x22b41be8, 0x22bc0000)
  from space 256K,   0% used [0x22bc0000, 0x22bc0000, 0x22c00000)
  to   space 256K,   0% used [0x22c00000, 0x22c00000, 0x22c40000)
 tenured generation   total 5504K, used 0K [0x25440000, 0x259a0000, 0x2a9a0000)
   the space 5504K,   0% used [0x25440000, 0x25440000, 0x25440200, 0x259a0000)
 compacting perm gen  total 12288K, used 462K [0x2a9a0000, 0x2b5a0000, 0x2e9a0000)
   the space 12288K,   3% used [0x2a9a0000, 0x2aa13878, 0x2aa13a00, 0x2b5a0000)
    ro space 10240K,  51% used [0x2e9a0000, 0x2eeccf58, 0x2eecd000, 0x2f3a0000)
    rw space 12288K,  54% used [0x2f3a0000, 0x2fa38f50, 0x2fa39000, 0x2ffa0000)

Dynamic libraries:
0x00400000 - 0x00424000     C:\Program Files\Java\jre6\bin\javaw.exe
0x7c910000 - 0x7c9c9000     C:\WINDOWS\system32\ntdll.dll
0x7c800000 - 0x7c906000     C:\WINDOWS\system32\kernel32.dll
0x77da0000 - 0x77e4c000     C:\WINDOWS\system32\ADVAPI32.dll
0x77e50000 - 0x77ee3000     C:\WINDOWS\system32\RPCRT4.dll
0x77fc0000 - 0x77fd1000     C:\WINDOWS\system32\Secur32.dll
0x7e390000 - 0x7e421000     C:\WINDOWS\system32\USER32.dll
0x77ef0000 - 0x77f39000     C:\WINDOWS\system32\GDI32.dll
0x76320000 - 0x7633d000     C:\WINDOWS\system32\IMM32.DLL
0x7c340000 - 0x7c396000     C:\Program Files\Java\jre6\bin\msvcr71.dll
0x6d7f0000 - 0x6da96000     C:\Program Files\Java\jre6\bin\client\jvm.dll
0x76ae0000 - 0x76b0f000     C:\WINDOWS\system32\WINMM.dll
0x5de20000 - 0x5de28000     C:\WINDOWS\system32\rdpsnd.dll
0x762f0000 - 0x76300000     C:\WINDOWS\system32\WINSTA.dll
0x6fee0000 - 0x6ff35000     C:\WINDOWS\system32\NETAPI32.dll
0x77be0000 - 0x77c38000     C:\WINDOWS\system32\msvcrt.dll
0x76ba0000 - 0x76bab000     C:\WINDOWS\system32\PSAPI.DLL
0x6d7a0000 - 0x6d7ac000     C:\Program Files\Java\jre6\bin\verify.dll
0x6d320000 - 0x6d33f000     C:\Program Files\Java\jre6\bin\java.dll
0x6d280000 - 0x6d288000     C:\Program Files\Java\jre6\bin\hpi.dll
0x6d7e0000 - 0x6d7ef000     C:\Program Files\Java\jre6\bin\zip.dll
0x68000000 - 0x68036000     C:\WINDOWS\system32\rsaenh.dll
0x76960000 - 0x76a16000     C:\WINDOWS\system32\USERENV.dll
0x6d600000 - 0x6d613000     C:\Program Files\Java\jre6\bin\net.dll
0x719f0000 - 0x71a07000     C:\WINDOWS\system32\WS2_32.dll
0x719e0000 - 0x719e8000     C:\WINDOWS\system32\WS2HELP.dll
0x71990000 - 0x719d0000     C:\WINDOWS\System32\mswsock.dll
0x76ed0000 - 0x76ef7000     C:\WINDOWS\system32\DNSAPI.dll
0x76d10000 - 0x76d29000     C:\WINDOWS\system32\iphlpapi.dll
0x76f60000 - 0x76f68000     C:\WINDOWS\System32\winrnr.dll
0x76f10000 - 0x76f3d000     C:\WINDOWS\system32\WLDAP32.dll
0x76f70000 - 0x76f76000     C:\WINDOWS\system32\rasadhlp.dll
0x10000000 - 0x10055000     C:\Documents and Settings\admaxg\LocalSettings\Temp\jna2907102074982287093.dll
0x03030000 - 0x03cfa000     C:\Documents and Settings\admaxg\workspace\testatih\libs\libatih1211b_x86.dll
0x10200000 - 0x10372000     C:\WINDOWS\system32\MSVCR100D.dll
0x5b090000 - 0x5b0c8000     C:\WINDOWS\system32\uxtheme.dll
0x74690000 - 0x746dc000     C:\WINDOWS\system32\MSCTF.dll
0x75140000 - 0x7516e000     C:\WINDOWS\system32\msctfime.ime
0x774a0000 - 0x775de000     C:\WINDOWS\system32\ole32.dll

VM Arguments:
jvm_args: -Dfile.encoding=Cp1252 
java_command: test.JnaTest
Launcher Type: SUN_STANDARD

Environment Variables:
PATH=C:/Program Files/Java/jre6/bin/client;C:/Program Files/Java/jre6/bin;C:/Program     Files/Java/jre6/lib/i386;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\MinGW\bin
USERNAME=admaxg
OS=Windows_NT
PROCESSOR_IDENTIFIER=x86 Family 6 Model 2 Stepping 3, GenuineIntel



---------------  S Y S T E M  ---------------

OS: Windows XP Build 2600 Service Pack 3

CPU:total 1 (1 cores per cpu, 1 threads per core) family 6 model 2 stepping 3, cmov, cx8, fxsr, mmx, sse, sse2, sse3, popcnt

Memory: 4k page, physical 523800k(15984k free), swap 1684276k(146616k free)

vm_info: Java HotSpot(TM) Client VM (19.1-b02) for windows-x86 JRE (1.6.0_24-b07), built on Feb  2 2011 17:44:41 by "java_re" with MS VC++ 7.1 (VS2003)

time: Mon May 02 12:19:11 2011
elapsed time: 0 seconds

你认为两个平台之间的JNA映射应该是不同的吗?我是否会错过某些平台特定选项?我该如何解决这个问题?

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

您的代码期望第一个参数是可写内存缓冲区。从Java你传递一个(未初始化的)指针指针。

你的C代码还释放了一个传递给它的指针,在JNA调用的情况下,它不拥有(内存也不一定以与“free”操作一致的方式分配)。

你应该使用com.jna.Memory或原始数组作为缓冲区,而不是传入PointerByReference,你的C代码应该释放第二个参数(如果是,则分配用malloc输入参数。)

答案 1 :(得分:0)

我使用mingw代替VisualC ++编译C原始代码并且它可以工作。