c - JNA simple funktionsopkald fungerer på linux (x64), men ikke på windows (x86)

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at køre følgende C-funktion fra Java ved hjælp af JNA, men jeg får en fejl (ugyldig hukommelsesadgang) på x86 windows (DLL), men ikke i x64 linux (.SO).


c funktion



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


C-test: fungerer i begge platforme (Eclipse CDT/MVC ++)



Når funktionen er udsat via Linux Shared Library eller Windows DLL og kaldes direkte i C, er resultatet OK.


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


Eller ved hjælp af 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
",out);
        fprintf(stdout,"res: \%s
",res);

        FreeLibrary( hInst );
}


Problemet vises med JNA.


Bibliotek



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


Java test: fungerer kun med 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 fejl



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 crash rapport



#
# 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 FilesJavajre6injavaw.exe
0x7c910000 - 0x7c9c9000     C:WINDOWSsystem32
tdll.dll
0x7c800000 - 0x7c906000     C:WINDOWSsystem32kernel32.dll
0x77da0000 - 0x77e4c000     C:WINDOWSsystem32ADVAPI32.dll
0x77e50000 - 0x77ee3000     C:WINDOWSsystem32RPCRT4.dll
0x77fc0000 - 0x77fd1000     C:WINDOWSsystem32Secur32.dll
0x7e390000 - 0x7e421000     C:WINDOWSsystem32USER32.dll
0x77ef0000 - 0x77f39000     C:WINDOWSsystem32GDI32.dll
0x76320000 - 0x7633d000     C:WINDOWSsystem32IMM32.DLL
0x7c340000 - 0x7c396000     C:Program FilesJavajre6inmsvcr71.dll
0x6d7f0000 - 0x6da96000     C:Program FilesJavajre6inclientjvm.dll
0x76ae0000 - 0x76b0f000     C:WINDOWSsystem32WINMM.dll
0x5de20000 - 0x5de28000     C:WINDOWSsystem32
dpsnd.dll
0x762f0000 - 0x76300000     C:WINDOWSsystem32WINSTA.dll
0x6fee0000 - 0x6ff35000     C:WINDOWSsystem32NETAPI32.dll
0x77be0000 - 0x77c38000     C:WINDOWSsystem32msvcrt.dll
0x76ba0000 - 0x76bab000     C:WINDOWSsystem32PSAPI.DLL
0x6d7a0000 - 0x6d7ac000     C:Program FilesJavajre6inverify.dll
0x6d320000 - 0x6d33f000     C:Program FilesJavajre6injava.dll
0x6d280000 - 0x6d288000     C:Program FilesJavajre6inhpi.dll
0x6d7e0000 - 0x6d7ef000     C:Program FilesJavajre6inzip.dll
0x68000000 - 0x68036000     C:WINDOWSsystem32
saenh.dll
0x76960000 - 0x76a16000     C:WINDOWSsystem32USERENV.dll
0x6d600000 - 0x6d613000     C:Program FilesJavajre6in
et.dll
0x719f0000 - 0x71a07000     C:WINDOWSsystem32WS2\_32.dll
0x719e0000 - 0x719e8000     C:WINDOWSsystem32WS2HELP.dll
0x71990000 - 0x719d0000     C:WINDOWSSystem32mswsock.dll
0x76ed0000 - 0x76ef7000     C:WINDOWSsystem32DNSAPI.dll
0x76d10000 - 0x76d29000     C:WINDOWSsystem32iphlpapi.dll
0x76f60000 - 0x76f68000     C:WINDOWSSystem32winrnr.dll
0x76f10000 - 0x76f3d000     C:WINDOWSsystem32WLDAP32.dll
0x76f70000 - 0x76f76000     C:WINDOWSsystem32
asadhlp.dll
0x10000000 - 0x10055000     C:Documents and SettingsadmaxgLocalSettingsTempjna2907102074982287093.dll
0x03030000 - 0x03cfa000     C:Documents and Settingsadmaxgworkspace	estatihlibslibatih1211b\_x86.dll
0x10200000 - 0x10372000     C:WINDOWSsystem32MSVCR100D.dll
0x5b090000 - 0x5b0c8000     C:WINDOWSsystem32uxtheme.dll
0x74690000 - 0x746dc000     C:WINDOWSsystem32MSCTF.dll
0x75140000 - 0x7516e000     C:WINDOWSsystem32msctfime.ime
0x774a0000 - 0x775de000     C:WINDOWSsystem32ole32.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:WINDOWSsystem32;C:WINDOWS;C:WINDOWSSystem32Wbem;C:MinGWin
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


Tror du, at JNA kortlægning skal være anderledes mellem begge platforme? Savner jeg nogle platformspecifikke muligheder? Hvordan kan jeg løse dette?


Tak for din hjælp

Bedste reference


Din kode forventer, at det første argument er en skrivbar hukommelsesbuffer. Fra Java overfører du det en (uninitialiseret) peger til en peger.


Din C-kode frigør også en pointer, der sendes til den, hvilket i tilfælde af JNA-opkaldet ikke ejer (hukommelsen blev heller ikke nødvendigvis tildelt på en måde, der var i overensstemmelse med driften af ​​'fri').


Du skal bruge com.jna.Memory eller et primitivt array som en buffer i stedet for at passere i PointerByReference, og din C-kode skal ikke frigive det andet argument (eller hvis det gør det, tildele input argumentet med malloc).

Andre referencer 1


Jeg kompilerer C-originalkoden med mingw i stedet for VisualC ++, og det virker.