jjzjj

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

coder 2024-06-22 原文

我正在尝试使用 JNA 从 Java 运行以下 C 函数,但我在 x86 windows (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中调用,结果OK。

...
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;

或者使用动态链接库:

...
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 映射应该有所不同吗?我是否错过了一些特定于平台的选项?我该如何解决这个问题?

谢谢你的帮助

最佳答案

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

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

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

关于c - JNA 简单函数调用适用于 linux (x64) 但不适用于 Windows (x86),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5856149/

有关c - JNA 简单函数调用适用于 linux (x64) 但不适用于 Windows (x86)的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  6. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

随机推荐