Простой вызов функции JNA работает в Linux (x64), но не в Windows (x86)

Я пытаюсь запустить следующую функцию C из Java с помощью JNA, но получаю сообщение об ошибке (недопустимый доступ к памяти) в окнах x86 (DLL), но не в Linux x64 (.SO).

с функция

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 должно быть разным для обеих платформ? Я пропустил какие-то специфичные для платформы параметры? Как я могу это решить?

Спасибо за вашу помощь


person matg    schedule 02.05.2011    source источник


Ответы (2)


Ваш код ожидает, что первый аргумент будет записываемым буфером памяти. Из Java вы передаете (неинициализированный) указатель на указатель.

Ваш код C также освобождает переданный ему указатель, который в случае вызова JNA ему не принадлежит (память также не обязательно даже выделялась способом, совместимым с операцией «свободно»).

Вы должны использовать com.jna.Memory или примитивный массив в качестве буфера вместо передачи PointerByReference, и ваш код C не должен не освобождать второй аргумент (или, если он освобождает, выделять входной аргумент с помощью маллок).

person technomage    schedule 03.05.2011
comment
Спасибо, я пробовал, но тоже не получается и работает как под линуксом. - person matg; 04.05.2011

Я компилирую исходный код C с помощью mingw вместо VisualC++, и он работает.

person matg    schedule 05.05.2011