简体   繁体   English

使用POSIX消息队列运行JNA示例

[英]Running a JNA example with POSIX message queues

I need to communicate a Java application and a C process via POSIX message queue, and I would like to do it using JNA. 我需要通过POSIX消息队列传递Java应用程序和C进程,我想使用JNA进行通信。

After some research, reading and your help, I started with a simple Java application which tries to create a message queue. 经过研究,阅读和您的帮助,我从一个简单的Java应用程序开始,该应用程序试图创建一个消息队列。

/** Simple example of JNA interface mapping and usage. */
public class HelloJNAWorld {

    // This is the standard, stable way of mapping, which supports extensive
    // customization and mapping of Java to native types.

     public interface IPCLibrary extends Library {
        IPCLibrary INSTANCE = (IPCLibrary)
                Native.loadLibrary("c",IPCLibrary.class);


        int msgget(NativeLong key, int msgflg);

    }

    public static void main(String[] args) {

        int id = IPCLibrary.INSTANCE.msgget(new NativeLong(12500), 0600|1);


        if(id<0){
                System.out.println("Error creating message queue. Id:"+id);
                System.out.println(Native.getLastError());
        }else{
                System.out.println("Message queue id:" + idCola);
        }

    }
}

I thought msgctl was the simplest method to map because it's just int msgget(key_t key, int msgflag); 我以为msgctl是最简单的映射方法,因为它只是int msgget(key_t key, int msgflag); . I have assumed that I could map key_t as a NativeLong but msget is returning -1. 我假设我可以将key_t映射为NativeLong但是msget返回-1。 So I've checked lastError and the value returned is 2, which means "No such file or directory" according to errno codes. 因此,我检查了lastError ,返回的值为2,根据errno代码,这意味着“没有这样的文件或目录”。

Could you help me with this? 你能帮我吗? Maybe key_ t should be mapped in another way? 也许key_ t应该以其他方式映射? Maybe I need more libraries or something like that? 也许我需要更多的图书馆或类似的东西?

Since no one answer this question, and some could need the help I needed those days, I'm posting my test class code here. 由于没有人回答这个问题,有些人可能需要我当时需要的帮助,因此我在这里发布了测试类代码。 :-) :-)

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.Structure;

/** Simple example of JNA interface mapping and usage. */
public class HelloJNAWorld {

    // This is the standard, stable way of mapping, which supports extensive
    // customization and mapping of Java to native types.

    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)
        Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),CLibrary.class);


        void printf(String format, Object... args);


    }

    public interface IPCLibrary extends Library {
        IPCLibrary INSTANCE = (IPCLibrary)           
        Native.loadLibrary("c",IPCLibrary.class);



        class WaitQueue extends Structure{

        }


        // mapping msqid_ds structure
        class MsqidDs extends Structure{
            long msg_stime;       /* last msgsnd time */
            long msg_rtime;       /* last msgrcv time */
            long msg_ctime;       /* last change time */
            short msg_cbytes;
            short msg_qnum;
            short msg_qbytes;      /* max number of bytes on queue */
            short msg_lspid;       /* pid of last msgsnd */
            short msg_lrpid;       /* last receive pid */
        }

        // END mapping msqid_ds structure

        class MsgBuf extends Structure{
            NativeLong mtype; /* type of message */
            byte mtext[] = new byte[1];
        }


        class MyMsgBuf extends MsgBuf{
            public NativeLong messageKind;
            public byte[] contenido = new byte[1024];
        }

        // Initialize queue, or if it exists, get it            
        int msgget(NativeLong key, int msgflg);
        // Send messages to queue
        // int msgsnd(int msqid, struct msgbuf *ptrkey, int length, int flag);
        int msgsnd(int msqid, MsgBuf ptrkey, int msgsz, int msgflg);
        // Receive messages from queue
        // int msgrcv(int msqid, struct msgbuf *ptrkey, int length, long msgtype, int flag);
        int msgrcv(int msqid, MsgBuf ptrkey, int length, long msgtype, int flag);            

    }

    public static void main(String[] args) {

        int idCola = IPCLibrary.INSTANCE.msgget(new NativeLong(12500), 0);            

        if(idCola<0){
            System.out.println("The queue can't be created. IdCola:"+idCola);           
            System.out.println("Error msgget: " + Native.getLastError());
        }else{
            System.out.println("Queue with id:" + idCola + "has been recovered");           
            // Send message
            IPCLibrary.MyMsgBuf mensaje = new IPCLibrary.MyMsgBuf();
            mensaje.tipoMensaje = new NativeLong(1);
            mensaje.contenido = "Sending message".getBytes();
            int devSend = IPCLibrary.INSTANCE.msgsnd(idCola, mensaje, mensaje.contenido.length, 1);
            if(devSend != 0){
                System.out.println("Send response: "+devSend);
                System.out.println("Error value: " + Native.getLastError());
            }
        }

        // Receiving message
        IPCLibrary.MyMsgBuf mensajeRecibido =  new IPCLibrary.MyMsgBuf();        
        int bytesRecibidos = IPCLibrary.INSTANCE.msgrcv(idCola, mensajeRecibido, mensajeRecibido.contenido.length, 1234, 0);
        if(bytesRecibidos > 0){
            System.out.println("C message has been received: " + new String(mensajeRecibido.contenido));
        }else{
            System.out.println("msgrcv error: " + Native.getLastError());
        }


        // Send closing message
        IPCLibrary.MyMsgBuf mensajeCierre = new IPCLibrary.MyMsgBuf();
        mensajeCierre.tipoMensaje = new NativeLong(2);
        mensajeCierre.contenido = "Closing queue".getBytes();
        int devSend = IPCLibrary.INSTANCE.msgsnd(idCola, mensajeCierre, mensajeCierre.contenido.length, 1);
        if(devSend != 0){
            System.out.println("Send response: "+devSend);
            System.out.println("Error value: " + Native.getLastError());
        }            

    }
}

I really hope this can help someone else. 我真的希望这可以帮助其他人。

I cleaned up your code and got it running. 我清理了您的代码并使其运行。 You need two tasks . 您需要完成两项任务。 one to send and one to receive. 一个发送,一个接收。 just replace the main() in your previous post with the main()'s below. 只需将您以前的帖子中的main()替换为下面的main()即可。 It worked for me. 它为我工作。 Thanks for posting your efforts for me to start with. 感谢您为我提供的帮助。 Also see kirk.c and spock.c for a good c example http://beej.us/guide/bgipc/output/html/multipage/mq.html 另请参见kirk.c和spock.c,以获得一个很好的c示例http://beej.us/guide/bgipc/output/html/multipage/mq.html

   public static void main(String[] args) {
   double SLEEP_MINUTES = 0.1;
   int IPC_CREAT = 01000;  // starts with 0 so its octal or 512 
   int IPC_EXCL  = 02000;
   int IPC_NOWAIT  = 04000;
   int MSG_EXCEPT = 020000;
   int MSG_NOERROR =  010000;  // truncate the message if its to big     
   int msgflg_msgrcv = MSG_NOERROR; //  truncate the message if its to big
   int msgflg_msgget = 0666 | IPC_CREAT;
   int msgflg_msgsnd = 0;
   int msgtype_msgrcv = 0; // read them all
   NativeLong msgtype_msgsnd = new NativeLong(1); // just needs to be a positive number
   NativeLong msgkey = new NativeLong(12500);  



    int msqid = IPCLibrary.INSTANCE.msgget(msgkey, msgflg_msgget);            

    if(msqid<0)
    {
        System.out.println("The queue can't be created. msqid:"+msqid);           
        System.out.println("Error msgget: " + Native.getLastError());
        System.exit(0);
    }

    System.out.println("Queue with id:" + msqid + "has been found or created");  
    for(int i=0;i<100;i++)
    {
        // Send message
        IPCLibrary.MyMsgBuf message = new IPCLibrary.MyMsgBuf();
        message.messagetype = msgtype_msgsnd;
        message.content = ("Sending message"+i+'\0').getBytes();           // add 1 for the '\0'
        int devSend = IPCLibrary.INSTANCE.msgsnd(msqid, message, message.content.length+1,
                msgflg_msgsnd);
        if(devSend != 0)
        {
            System.out.println("Send response: "+devSend);
            System.out.println("Error value: " + Native.getLastError());
            System.exit(0);
        }
        System.out.println("Sent "+i);            
        try
        {
            Thread.sleep((long)(SLEEP_MINUTES*60.0*1000.0)); 
        }
        catch (InterruptedException e) 
        {
            System.out.println("InterruptedException while writing");
            System.out.println(e.getMessage());                 
        }

    }

}


     public static void main(String[] args) {
// found these in /usr/include/bits/*.h
int IPC_CREAT = 01000;  // remember if it starts with a '0' its octal or 512 
int IPC_EXCL  = 02000;
int IPC_NOWAIT  = 04000;
int MSG_EXCEPT = 020000;
int MSG_NOERROR =  010000;  // truncate the message if its to big     

int msgflg_msgrcv = MSG_NOERROR; //  truncate the message if its to big
int msgflg_msgget = 0666 | IPC_CREAT; // create the queue if its not there , let everybody read and write
int msgtype_msgrcv = 0; // read them all
NativeLong msgtype_msgsnd = new NativeLong(1); // just needs to be a positive number
NativeLong msgkey = new NativeLong(12500);  

    int msqid = IPCLibrary.INSTANCE.msgget(msgkey, msgflg_msgget);            
    if(msqid<0)
    {
        System.out.println("The queue can't be created. msqid:"+msqid);           
        System.out.println("Error msgget: " + Native.getLastError());
        System.exit(0);
    }

    System.out.println("Queue with id:" + msqid + "has been found or was created");  
    for(int i=0;i<100;i++)
    {
        IPCLibrary.MyMsgBuf message =  new IPCLibrary.MyMsgBuf();        
        int ret = IPCLibrary.INSTANCE.msgrcv(msqid, message, message.content.length,
                msgtype_msgrcv,msgflg_msgrcv);
        if(ret > 0)
        {
            System.out.println("message has been received: " + ret);
            System.out.println(new String(message.content));
        }
        else
        {
            System.out.println("msgrcv error: " + Native.getLastError());
        }
    }

   }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM