我正在尝试使用JNA从Java运行以下C函数,但是我在x86窗口(DLL)上遇到错误(无效内存访问)但在x64 linux(.SO)中没有。
char* testcopy(char* out,char* in)
{
strcpy(out,in);
free(in);
return out;
};
当函数通过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;
}
...
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));
...
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)
...
#
# 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映射应该是不同的吗?我是否会错过某些平台特定选项?我该如何解决这个问题?
感谢您的帮助
答案 0 :(得分:2)
您的代码期望第一个参数是可写内存缓冲区。从Java你传递一个(未初始化的)指针指针。
你的C代码还释放了一个传递给它的指针,在JNA调用的情况下,它不拥有(内存也不一定以与“free”操作一致的方式分配)。
你应该使用com.jna.Memory或原始数组作为缓冲区,而不是传入PointerByReference,你的C代码应该不释放第二个参数(如果是,则分配用malloc输入参数。)
答案 1 :(得分:0)
我使用mingw代替VisualC ++编译C原始代码并且它可以工作。