栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用JNA和Ada的Interface.C软件包将Ada动态库与Java接口

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用JNA和Ada的Interface.C软件包将Ada动态库与Java接口

这是我使用JNA和Ada的

Interface.C
软件包设法将Java与Ada库接口的方法。

dll非常简单,此处提供的Ada和Java代码至少显示了

char*
as in或out参数的2种用法。

可以阅读以下文档:JNA文档,此Ada
Wiki
,Ada标准文档和其他一些Ada标准文档。

注意:请注意,以下Java代码可与任何匹配的C接口声明一起使用。请参阅

.h
发布后的建议 文件。当然,Java控制台的结果取决于DLL的实现。

初步检查

您需要在Java项目中包含

JNA.jar
jar和
JNA-Platform.jar
。参见JNA
GitHub进行下载。

确保使用一致的Java和Ada lib体系结构:即32位或64位。否则,JNA / Java将无法加载该库。

也不要忘记使用以下VM选项

-Djna.debug_load=true
来查看JNA的登录控制台!

您的Java项目/ bin文件夹应包含以下内容:

  • 产生的Ada DLL(使用给定的代码,它将是
    libadalib.dll
  • 你的
    libgnat-version.dll
  • 你的
    libgcc_s_seh-1.dll

首先,Ada部分:

请注意,您可能需要在自己的DLL DLL附近放置一些gnat DLL。我目前尚未将所有内容打包到自己的DLL中。

因此,您 可能 需要在产生的dll的同一文件夹(即Java项目的

/bin
目录)中包含以下文件:

  • 您的libgnat-version.dll
  • 您的libgcc_s_seh-1.dll

如果需要解决此问题,请使用DependancyWalker。(请参阅http://www.dependencywalker.com/)

有一个GPR选项可以激活/停用自动DLL详细说明,但我尚未对其进行测试。


Ada码

Ada库项目:

project adalib is    for Languages use ("Ada");    for Source_Dirs use (project'Project_Dir & "./src");    for Library_Kind use "dynamic"; -- for DLL    for Library_Name use project'Name; -- will produce "libadalib.dll"    for Library_Interface use ("ada_interface");    for Library_Dir use project'Project_Dir & "./dll";    for Library_Src_Dir use project'Project_Dir & "./dll";    -- include other DLL / .a here if needed    -- for Library_Options use ("-L" & path_to_lib,    --    "-l" & path_to_lib      --   );    -- define your favorite compiler, builder, binder, linker optionsend adalib;

./src ada文件

ada_interface.ads

pragma Ada_2012;with Interfaces.C;with Interfaces.C.Strings;package ada_interface is    procedure myService (   inBuffer       : in     Interfaces.C.Strings.chars_ptr; -- as in   anInteger      : in     Interfaces.C.int;   outBuffer      : in     Interfaces.C.Strings.chars_ptr; -- as out buffer   outBufferSize  : in     Interfaces.C.int;    -- max out buffer size   usedBufferSize :    out Interfaces.C.int  );    pragma Export (Convention    => C,        Entity        => myService,        External_Name => "Renamed_myService");end ada_interface;

ada_interface.adb

pragma Ada_2012;with Ada.Text_IO;with Interfaces.C.Strings;package body ada_interface is    procedure myService (   inBuffer       : in     Interfaces.C.Strings.chars_ptr; -- as in   anInteger      : in     Interfaces.C.int;   outBuffer      : in     Interfaces.C.Strings.chars_ptr; -- as out buffer   outBufferSize  : in     Interfaces.C.int;    -- max out buffer size   usedBufferSize :    out Interfaces.C.int  )    is       -- if elaboration needs to be explicitly called       procedure ada_elaboration;       pragma import (C, ada_elaboration, "adalibinit"); -- "<name of lib>init". May not be needed with proper options in GPR       Required_Length : Natural := Natural (outBufferSize);       myString : String := "This is a sample string";       use type Interfaces.C.size_t;    begin       ada_elaboration;       --       Ada.Text_IO.Put_Line ("======= inside myService");       -- print the string given by char*       Ada.Text_IO.Put_Line (Interfaces.C.Strings.Value (inBuffer));       -- the int       Ada.Text_IO.Put_Line (Natural'Image (Natural (anInteger)));       -- current value of the char* to be used as OUT buffer       Ada.Text_IO.Put_Line (Interfaces.C.Strings.Value (outBuffer));       -- use the char* to be used as out       Interfaces.C.Strings.Update         (Item   => outBuffer,          Offset => 0,          Str    => myString & Interfaces.C.To_Ada (Interfaces.C.nul), -- "& Interfaces.C.To_Ada(Interfaces.C.nul)" is equivalent to "& Character'Val(0)"          Check  => false);       usedBufferSize := Interfaces.C.int (Interfaces.C.Strings.Strlen (outBuffer) - 1); -- see later java pre and traces    end myService;end ada_interface;

现在的Java代码:

用于将服务加载和映射到库的类:

package tst;import com.sun.jna.Library;import com.sun.jna.Native;import com.sun.jna.Pointer;import com.sun.jna.ptr.IntByReference;public class Ada_Lib {    public interface My_Ada_Lib extends Library {        My_Ada_Lib instance = (My_Ada_Lib) Native.loadLibrary("libadalib", My_Ada_Lib.class);        My_Ada_Lib synchronizedInstance = (My_Ada_Lib) Native.synchronizedLibrary(instance);    void Renamed_myService (  Pointer inBuffer,  int anInteger,  byte[] outBuffer,  int outBufferSize,  IntByReference usedBufferSize );    }}

类调用库

package tst;import com.sun.jna.Memory;import com.sun.jna.Native;import com.sun.jna.Pointer;import com.sun.jna.ptr.IntByReference;import tst.Ada_Lib.My_Ada_Lib;public class TestMyLib {    private static My_Ada_Lib theLib = Ada_Lib.My_Ada_Lib.synchronizedInstance;    public static void main(String[] args) {        String lorem = "Sin autem ad adulescentiam perduxissent, dirimi tamen interdum contentione vel uxoriae condicionis vel commodi alicuius, quod idem adipisci uterque non posset. Quod si qui longius in amicitia provecti essent, tamen saepe labefactari, si in honoris contentionem incidissent; pestem enim nullam maiorem esse amicitiis quam in plerisque pecuniae cupiditatem, in optimis quibusque honoris certamen et gloriae; ex quo inimicitias maximas saepe inter amicissimos exstitisse." +     "n" +     "Quanta autem vis amicitiae sit, ex hoc intellegi maxime potest, quod ex infinita societate generis humani, quam conciliavit ipsa natura, ita contracta res est et adducta in angustum ut omnis caritas aut inter duos aut inter paucos iungeretur." +     "n" +     "Haec subinde Constantius audiens et quaedam referente Thalassio doctus, quem eum odisse iam conpererat lege communi, scribens ad Caesarem blandius adiumenta paulatim illi subtraxit, sollicitari se simulans ne, uti est militare otium fere tumultuosum, in eius perniciem conspiraret, solisque scholis iussit esse contentum palatinis et protectorum cum Scutariis et Gentilibus, et mandabat Domitiano, ex comite largitionum, praefecto ut cum in Syriam venerit, Gallum, quem crebro acciverat, ad Italiam properare blande hortaretur et verecunde.n";        // in params        int inputInt = 25;        Pointer p_Lorem = new Memory(lorem.length()+1); // +1 for C's         p_Lorem.setString(0, lorem); // offset 0, no need to start at another offset        // in param but to used for out buffer        String stubOut = "Hello World ! 0123456789";        int maxBufferSize = (stubOut.length());        byte[] buffer = new byte[maxBufferSize];        buffer = stubOut.getBytes();        IntByReference usedBufferSize = new IntByReference(0); // any value works, since it is used as out param        System.out.println("-------------------- Call to Lib ----------------------------");        // call the lib !        theLib.Renamed_myService(p_Lorem, inputInt, buffer, maxBufferSize, usedBufferSize);        System.out.println("--------------------- Back to java --------------------------");        System.out.println("In Java: used buffer size         = " + usedBufferSize.getValue());        System.out.println("In Java: read outBuffer as String = " + Native.toString(buffer));        System.out.println("In Java: read outBuffer as String with returned used buffer size = " + new String(buffer,0,usedBufferSize.getValue()));    }}

来自Java控制台的输出(JNA debug为true)

Looking in classpath from sun.misc.Launcher$AppClassLoader@4e0e2f2a for /com/sun/jna/win32-x86-64/jnidispatch.dllFound library resource at jar:file:/ [...]Looking for library 'libadalib'Adding paths from jna.library.path: nullTrying libadalib.dllAdding system paths: []Trying libadalib.dllLooking for lib- prefixTrying liblibadalib.dllLooking in classpath from sun.misc.Launcher$AppClassLoader@4e0e2f2a for libadalibFound library resource at file:/<path>/TestMyLib/bin/libadalib.dllLooking in <path>TestMyLibbinlibadalib.dllFound library 'libadalib' at <path>TestMyLibbinlibadalib.dll-------------------- Call to Lib ----------------------------======= inside myServiceSin autem ad adulescentiam perduxissent, dirimi tamen interdum contentione vel uxoriae condicionis vel commodi alicuius, quod idem adipisci uterque non posset. Quod si qui longius in amicitia provecti essent, tamen saepe labefactari, si in honoris contentionem incidissent; pestem enim nullam maiorem esse amicitiis quam in plerisque pecuniae cupiditatem, in optimis quibusque honoris certamen et gloriae; ex quo inimicitias maximas saepe inter amicissimos exstitisse.Quanta autem vis amicitiae sit, ex hoc intellegi maxime potest, quod ex infinita societate generis humani, quam conciliavit ipsa natura, ita contracta res est et adducta in angustum ut omnis caritas aut inter duos aut inter paucos iungeretur.Haec subinde Constantius audiens et quaedam referente Thalassio doctus, quem eum odisse iam conpererat lege communi, scribens ad Caesarem blandius adiumenta paulatim illi subtraxit, sollicitari se simulans ne, uti est militare otium fere tumultuosum, in eius perniciem conspiraret, solisque scholis iussit esse contentum palatinis et protectorum cum Scutariis et Gentilibus, et mandabat Domitiano, ex comite largitionum, praefecto ut cum in Syriam venerit, Gallum, quem crebro acciverat, ad Italiam properare blande hortaretur et verecunde. 25Hello World ! 0123456789--------------------- Back to java --------------------------In Java: used buffer size         = 22In Java: read outBuffer as String = This is a sample string // reads the full bufferIn Java: read outBuffer as String with returned used buffer size = This is a sample strin // reads a length of 22 (so the 'g' is missing)

现在,也可以使用匹配的.h文件轻松将Ada库与C或C ++接口:

void myService (char* inBuffer,  // as in string     int   anInteger, // as in param     char* outBuffer, // used as out buffer, but initalized by calling pre     int   outBufferSize, // the initaliaed size     int   usedBufferSize // used as out param, the actually used size);

从Eclipse调用时如何调试lib?

使用Gnat Pro
Studio(GPS),您可以进入调试器视图,并将gdb附加到Java应用程序进程的PID(对于Windows)。但是,如果没有以下技巧,您将无法设置断点。

诀窍是在DLL中有一个无限循环(出于开发目的)。

身体:

while flag loop    null;end loop;

广告文件:

flag : boolean := true; -- in private part

一旦gdb设法附加到正在运行的DLL代码(无限循环),gdb就会崩溃。

在循环中放置一个断点,然后在gdb中输入类型

c
。它将在您的循环中中断。

在代码中的其他地方放置另一个断点,然后键入follwong

set flag := false
,然后输入
c

现在,gdb应该继续到下一个断点。

(或使用“ n”(下一条)gdb指令自行调试。)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/438094.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号