2012-08-09 53 views
0

我需要通过POSIX消息队列来通信Java应用程序和C进程,并且我想使用JNA来执行此操作。使用POSIX消息队列运行JNA示例

经过一番研究,阅读和你的帮助,我开始使用一个简单的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); 
     } 

    } 
} 

我认为msgctl是地图,因为它只是int msgget(key_t key, int msgflag);最简单的方法。我假设我可以将key_t映射为NativeLong,但msget返回-1。所以我检查了lastError,返回的值是2,表示根据errno代码“没有这样的文件或者 ”。

你能帮我解决吗?也许key_ t应该以另一种方式映射?也许我需要更多的库或类似的东西?

+0

我想我发现了什么。我没有注意到错误代码2意味着“没有这样的文件或目录”的通用方式。但是,应用到“msgget”错误列表中意味着“没有消息队列存在,并且msgflg没有断言IPC_CREAT。”所以我查找了IPC_CREAT的值,并更改了“int id = IPCLibrary.INSTANCE.msgget(new NativeLong(12500),0600 | 1);”为另一个“int id = IPCLibrary.INSTANCE.msgget(新的NativeLong(12500),0600 | 01000);”。现在msgget返回0,这似乎并不好,但我正在寻找答案。 – Anne 2012-08-09 09:10:01

回答

1

由于没有人回答这个问题,有些人可能需要我需要那些天的帮助,所以我在这里发布我的测试类代码。 :-)

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()); 
     }    

    } 
} 

我真的希望这可以帮助别人。

0

我清理了你的代码,并让它运行。 你需要两个任务。一个发送,一个接收。 只需使用下面的main()函数替换上一篇文章中的main()。它为我工作。感谢您发布我的开始。 另见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()); 
     } 
    } 

    } 
}