我有一个在Linux上运行的Java应用程序,通过JNA与编写为C语言的共享对象的库进行对话。我希望能够在Windows上运行它,所以我在Cygwin下编译了库而没有问题
问题是当我尝试用.dll文件替换.so文件时,它在我调用函数时不起作用。
为了简化问题,我制作了一个非常简单的DLL和Java程序,如下所示:
test.h
__declspec(dllexport) void Test();
test.c的
#include <stdio.h>
#include "test.h"
void Test()
{
printf("Hello from Test!\n");
}
TestJNA.java
package testjna;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class TestJNA {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)Native.loadLibrary(System.getProperty("jna.library.path"), CLibrary.class);
void Test();
}
public static void main(String[] args) {
System.setProperty("jna.library.path", "absolute\\path\\to\\test.dll");
System.out.println("Starting test...");
CLibrary.INSTANCE.Test();
System.out.println("Test done!");
}
}
如果我在VS2015中编译DLL并将其复制,一切都按预期工作:
dist>java -jar TestJNA.jar
Starting test...
Hello from Test!
Test done!
然后我尝试在Cygwin中编译DLL,如下所示:
gcc -c test.c
gcc -shared -o test.dll test.o
这会生成一个DLL,如果我在Depedency Walker中加载它,我可以确认有一个导出的函数Test
。但是,当我将test.dll
和Cygwin1.dll
一起放入正确的目录并运行Java应用程序时,它将输出“Starting test ...”,然后在几秒钟后退出而没有任何错误。
我尝试删除__declspec(dllexport)
并按照here所述重新编译,但我仍然得到相同的结果。
我正在运行64位JVM:
C:\>java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
64位版本的Cygwin:
$ uname -a
CYGWIN_NT-6.1 computername 2.6.0(0.304/5/3) 2016-08-31 14:32 x86_64 Cygwin
我已经确认GCC生成的DLL是64位。
有谁知道我做错了什么?
以下是所请求的每个DLL的nm输出:
Cygwin编译的DLL
$ nm test.dll
000000042abc71b0 b .bss
000000042abc71b0 b .bss
000000042abc7040 b .bss
000000042abc71a0 b .bss
000000042abc71b0 b .bss
000000042abc7000 b .bss
000000042abc71b0 b .bss
000000042abc71b0 b .bss
000000042abc7000 b .bss
000000042abc71b0 b .bss
000000042abc71b0 b .bss
000000042abc7000 b .bss
000000042abc71b0 b .bss
000000042abc71b0 b .bss
000000042abc71b0 b .bss
000000042abc71b0 b .bss
000000042abc7030 b .bss
000000042abc16c8 t .ctors.65535
000000042abc2010 d .data
000000042abc2010 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2000 d .data
000000042abc2020 d .data
000000042abc2010 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2010 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abc2060 d .data
000000042abd2000 N .debug_abbrev
000000042abd244e N .debug_abbrev
000000042abd293f N .debug_abbrev
000000042abd28f0 N .debug_abbrev
000000042abd2852 N .debug_abbrev
000000042abd2260 N .debug_abbrev
000000042abd21e1 N .debug_abbrev
000000042abd2967 N .debug_abbrev
000000042abd2803 N .debug_abbrev
000000042abd28a1 N .debug_abbrev
000000042abcb0f0 N .debug_aranges
000000042abcb180 N .debug_aranges
000000042abcb000 N .debug_aranges
000000042abcb030 N .debug_aranges
000000042abcb060 N .debug_aranges
000000042abcb1b0 N .debug_aranges
000000042abcb090 N .debug_aranges
000000042abcb0c0 N .debug_aranges
000000042abcb120 N .debug_aranges
000000042abcb150 N .debug_aranges
000000042abd41a0 N .debug_frame
000000042abd4170 N .debug_frame
000000042abd4080 N .debug_frame
000000042abd4140 N .debug_frame
000000042abd4000 N .debug_frame
000000042abd41d0 N .debug_frame
000000042abd40f0 N .debug_frame
000000042abd4200 N .debug_frame
000000042abd40b0 N .debug_frame
000000042abcc000 N .debug_info
000000042abd0e5d N .debug_info
000000042abcc8de N .debug_info
000000042abd09a5 N .debug_info
000000042abd0749 N .debug_info
000000042abccc97 N .debug_info
000000042abcdf15 N .debug_info
000000042abd0c01 N .debug_info
000000042abd1091 N .debug_info
000000042abd04ed N .debug_info
000000042abd3000 N .debug_line
000000042abd31ce N .debug_line
000000042abd3b6b N .debug_line
000000042abd3c4f N .debug_line
000000042abd3afd N .debug_line
000000042abd311b N .debug_line
000000042abd3a8f N .debug_line
000000042abd3a21 N .debug_line
000000042abd3bd9 N .debug_line
000000042abd3459 N .debug_line
000000042abd6000 N .debug_loc
000000042abd65a3 N .debug_loc
000000042abd64f8 N .debug_loc
000000042abd7000 N .debug_ranges
000000042abd5024 N .debug_str
000000042abd5052 N .debug_str
000000042abd5000 N .debug_str
000000042abc9000 i .idata$2
000000042abc9014 i .idata$2
000000042abc906c i .idata$4
000000042abc90a4 i .idata$4
000000042abc9094 i .idata$4
000000042abc904c i .idata$4
000000042abc9084 i .idata$4
000000042abc903c i .idata$4
000000042abc9074 i .idata$4
000000042abc909c i .idata$4
000000042abc908c i .idata$4
000000042abc90ac i .idata$4
000000042abc9044 i .idata$4
000000042abc905c i .idata$4
000000042abc907c i .idata$4
000000042abc9054 i .idata$4
000000042abc9064 i .idata$4
000000042abc903c i .idata$4
000000042abc909c i .idata$4
000000042abc90dc i .idata$5
000000042abc90c4 i .idata$5
000000042abc90cc i .idata$5
000000042abc90e4 i .idata$5
000000042abc9114 i .idata$5
000000042abc9114 i .idata$5
000000042abc90ec i .idata$5
000000042abc90f4 i .idata$5
000000042abc90b4 i .idata$5
000000042abc90fc i .idata$5
000000042abc910c i .idata$5
000000042abc90b4 i .idata$5
000000042abc9124 i .idata$5
000000042abc9104 i .idata$5
000000042abc911c i .idata$5
000000042abc90d4 i .idata$5
000000042abc90bc i .idata$5
000000042abc91e0 i .idata$6
000000042abc9158 i .idata$6
000000042abc91cc i .idata$6
000000042abc9190 i .idata$6
000000042abc9180 i .idata$6
000000042abc91c0 i .idata$6
000000042abc912c i .idata$6
000000042abc91b8 i .idata$6
000000042abc9198 i .idata$6
000000042abc916c i .idata$6
000000042abc914c i .idata$6
000000042abc91a4 i .idata$6
000000042abc913c i .idata$6
000000042abc9234 i .idata$7
000000042abc9200 i .idata$7
000000042abc91f4 i .idata$7
000000042abc91fc i .idata$7
000000042abc9214 i .idata$7
000000042abc9210 i .idata$7
000000042abc920c i .idata$7
000000042abc9208 i .idata$7
000000042abc9204 i .idata$7
000000042abc91f8 i .idata$7
000000042abc9220 i .idata$7
000000042abc921c i .idata$7
000000042abc9230 i .idata$7
000000042abc922c i .idata$7
000000042abc9218 i .idata$7
000000042abc2060 d .jcr
000000042abc2060 d .jcr
000000042abc50a8 p .pdata
000000042abc509c p .pdata
000000042abc5090 p .pdata
000000042abc5084 p .pdata
000000042abc5078 p .pdata
000000042abc506c p .pdata
000000042abc5060 p .pdata
000000042abc5000 p .pdata
000000042abc5054 p .pdata
000000042abc5030 p .pdata
000000042abc5024 p .pdata
000000042abc50b4 p .pdata.startup
000000042abc3030 r .rdata
000000042abc3000 r .rdata
000000042abc3290 r .rdata$zzz
000000042abc3250 r .rdata$zzz
000000042abc3210 r .rdata$zzz
000000042abc30d0 r .rdata$zzz
000000042abc31d0 r .rdata$zzz
000000042abc3070 r .rdata$zzz
000000042abc3190 r .rdata$zzz
000000042abc3090 r .rdata$zzz
000000042abc32d0 r .rdata$zzz
000000042abc32f0 r .rdata$zzz
000000042abc3150 r .rdata$zzz
000000042abc3050 r .rdata$zzz
000000042abc3110 r .rdata$zzz
000000042abc15f0 t .text
000000042abc1000 t .text
000000042abc1090 t .text
000000042abc10b0 t .text
000000042abc10c0 t .text
000000042abc10d0 t .text
000000042abc11c0 t .text
000000042abc11d0 t .text
000000042abc11e0 t .text
000000042abc1210 t .text
000000042abc1220 t .text
000000042abc1600 t .text
000000042abc1610 t .text
000000042abc1620 t .text
000000042abc1630 t .text
000000042abc1640 t .text
000000042abc1640 t .text
000000042abc1650 t .text
000000042abc1660 t .text
000000042abc1670 t .text
000000042abc1680 t .text
000000042abc1690 t .text
000000042abc16a0 t .text
000000042abc16a8 t .text
000000042abc16b0 t .text
000000042abc16b0 t .text
000000042abc16b0 t .text
000000042abc16b0 t .text
000000042abc16b0 t .text.startup
0000000000000000 A .weak.__real__ZdaPv._cygwin_crt0_common
0000000000000000 A .weak.__real__ZdaPvRKSt9nothrow_t._cygwin_crt0_common
0000000000000000 A .weak.__real__ZdlPv._cygwin_crt0_common
0000000000000000 A .weak.__real__ZdlPvRKSt9nothrow_t._cygwin_crt0_common
0000000000000000 A .weak.__real__Znam._cygwin_crt0_common
0000000000000000 A .weak.__real__ZnamRKSt9nothrow_t._cygwin_crt0_common
0000000000000000 A .weak.__real__Znwm._cygwin_crt0_common
0000000000000000 A .weak.__real__ZnwmRKSt9nothrow_t._cygwin_crt0_common
000000042abc1000 T .weak._Jv_RegisterClasses.__dso_handle
000000042abc6044 r .xdata
000000042abc6060 r .xdata
000000042abc605c r .xdata
000000042abc6058 r .xdata
000000042abc6054 r .xdata
000000042abc6050 r .xdata
000000042abc6000 r .xdata
000000042abc603c r .xdata
000000042abc6038 r .xdata
000000042abc6028 r .xdata
000000042abc601c r .xdata
000000042abc6064 r .xdata.startup
U ___crt_xc_end__
U ___crt_xc_start__
U ___crt_xi_end__
U ___crt_xi_start__
U ___crt_xl_start__
U ___crt_xp_end__
U ___crt_xp_start__
U ___crt_xt_end__
U ___crt_xt_start__
000000042abc16c0 T ___CTOR_LIST__
000000042abc16d8 T ___DTOR_LIST__
000000042abc3310 T ___RUNTIME_PSEUDO_RELOC_LIST__
000000042abc3310 R ___RUNTIME_PSEUDO_RELOC_LIST_END__
U ___tls_end__
U ___tls_start__
000000042abc71d0 B __bss_end__
000000042abc7000 B __bss_start__
000000042abc16c0 T __CTOR_LIST__
000000042abc10b0 T __cxa_atexit
000000042abc2020 D __cygwin_cxx_malloc
000000042abc2068 D __data_end__
000000042abc2000 D __data_start__
0000000000000000 A __dll__
0000000000000000 A __dll_characteristics__
000000042abc10d0 t __dllMain
000000042abc2000 D __dso_handle
000000042abc16d8 T __DTOR_LIST__
000000042abc7000 B __dynamically_loaded
U __end__
0000000000000200 A __file_alignment__
000000042abc1080 T __gcc_deregister_frame
000000042abc1010 T __gcc_register_frame
000000042abc912c I __IAT_end__
000000042abc90b4 I __IAT_start__
000000002abc0000 A __image_base__
000000002abc0000 A __ImageBase
000000042abc90b4 I __imp___cxa_atexit
000000042abc90bc I __imp__impure_ptr
000000042abc90c4 I __imp_calloc
000000042abc90cc I __imp_cygwin_detach_dll
000000042abc90d4 I __imp_cygwin_internal
000000042abc90dc I __imp_dll_dllcrt0
000000042abc90e4 I __imp_free
000000042abc9114 I __imp_GetModuleHandleA
000000042abc911c I __imp_GetProcAddress
000000042abc90ec I __imp_malloc
000000042abc90f4 I __imp_posix_memalign
000000042abc90fc I __imp_puts
000000042abc9104 I __imp_realloc
000000042abc2060 d __JCR_END__
000000042abc2060 d __JCR_LIST__
000000042abc9234 I __lib64_libkernel32_a_iname
0000000000000000 A __loader_flags__
0000000000000000 A __major_image_version__
0000000000000004 A __major_os_version__
0000000000000005 A __major_subsystem_version__
0000000000000000 A __minor_image_version__
0000000000000000 A __minor_os_version__
0000000000000002 A __minor_subsystem_version__
000000042abc913c I __nm__impure_ptr
000000042abc3310 R __rt_psrelocs_end
0000000000000000 A __rt_psrelocs_size
000000042abc3310 R __rt_psrelocs_start
000000042abc3310 T __RUNTIME_PSEUDO_RELOC_LIST__
000000042abc3310 R __RUNTIME_PSEUDO_RELOC_LIST_END__
0000000000001000 A __section_alignment__
0000000000001000 A __size_of_heap_commit__
0000000000100000 A __size_of_heap_reserve__
0000000000001000 A __size_of_stack_commit__
0000000000200000 A __size_of_stack_reserve__
0000000000000003 A __subsystem__
000000042abc1220 T _cygwin_crt0_common
000000042abc10f0 T _cygwin_dll_entry
000000042abc11b0 T _cygwin_noncygwin_dll_entry
000000042abc71a0 B _fmode
000000042abc9000 I _head_cygwin1_dll
000000042abc9014 I _head_lib64_libkernel32_a
w _Jv_RegisterClasses
000000042abc1630 T _pei386_runtime_relocator
w _ZdaPv
w _ZdaPvRKSt9nothrow_t
w _ZdlPv
w _ZdlPvRKSt9nothrow_t
w _Znam
w _ZnamRKSt9nothrow_t
w _Znwm
w _ZnwmRKSt9nothrow_t
000000042abc1640 T calloc
000000042abc11e0 T cygwin_attach_dll
000000042abc11d0 T cygwin_detach_dll
000000042abc1650 T cygwin_internal
000000042abc15f0 T cygwin_premain0
000000042abc1600 T cygwin_premain1
000000042abc1610 T cygwin_premain2
000000042abc1620 T cygwin_premain3
000000042abc9220 I cygwin1_dll_iname
000000042abc1210 T dll_dllcrt0
000000042abc7008 b dll_index
000000042abc11c0 T DllMain
000000042abc1660 T free
000000042abc9114 i fthunk
000000042abc16a8 T GetModuleHandleA
000000042abc16a0 T GetProcAddress
000000042abc909c i hname
000000042abc1670 T malloc
000000042abc1680 T posix_memalign
000000042abc10c0 T puts
000000042abc1690 T realloc
000000042abc16b0 t register_frame_ctor
000000042abc7020 b storedHandle
000000042abc7010 b storedPtr
000000042abc7018 b storedReason
000000042abc1090 T Test
000000042abc7040 b u.52838
Visual Studio编译DLL
$ nm test.dll.vs
nm: test.dll.vs: no symbols
所以我尝试使用额外的参数-Wl,--out-implib=test.lib
在Cygwin中编译来创建.lib
文件。然后我在Visual Studio中创建了一个简单的测试程序,并链接到库文件并运行调试器。当试图调用该函数时,我得到以下异常:
Exception thrown at 0x0000000180117A37 (cygwin1.dll) in RunTestDLL.exe: 0xC0000005: Access violation writing location 0xFFFFFFFF00020000.
地址似乎随着尝试运行而改变。
这反过来导致我在StackOverflow here上的另一个线程,其中有人有类似的问题。基于该线程,听起来问题在于动态加载cygwin1.dll
而不是我的DLL。而且由于我似乎无法找到任何关于在堆栈中保留空间的信息,我得出的结论是,我现在想做的事情是不可能的。