15. juni 2004 - 14:45
Der er
10 kommentarer og
1 løsning
sende objekt til c program der forventer en struct
Hej Alle i kloge
Jeg er ved at lave et proram der skal sende et objekt til et c program. (som jeg ikke har råderet over) der forventer at modtage et struct.
Hvordan gør jeg det... jeg må indrømme at jeg er på ret bar bund.
Jeg har en ide om at jeg kan sende et objekt afsted, men jeg er ikke sikker på at det vil virke. Er der nogle her der har erfaring med dette problem?
Med venlig hilsen
Morten Skovborg
Du skal bruge JNI.
(jeg har skrevet en artikel om JNI)
Jeg vil mene at du skal skrive en Java klasse med native methods, og en
C/C++ implementation af disse som så kalder den eksisterende C kode. Muligvis
er det nemmere at sende simple data typer over som arguemnetr og så pakke dem i
en struct i C koden fremfor at sende et objekt med over og lave struct udfra
det.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <errno.h>
struct data
{
short int a;
long int b;
float c;
double d;
char e[5];
};
void swap(char *x,int n)
{
int i;
char tmp;
for(i=0;i<n/2;i++)
{
tmp=x[i];
x[i]=x[n-i-1];
x[n-i-1]=tmp;
}
}
int main(int argc,char *argv[])
{
WSADATA WSAData;
int sd,sd2,status,len,ix;
char *p;
struct sockaddr_in local;
struct data msg;
/* windows specifik */
WSAStartup(0x0101,&WSAData);
/* create socket */
sd=socket(AF_INET,SOCK_STREAM,0);
if(sd<0) {
printf("Error creating socket: %s\n",strerror(errno));
goto fin;
}
/* bind socket */
local.sin_family=AF_INET;
local.sin_port = htons(12345);
local.sin_addr.s_addr = INADDR_ANY;
status=bind(sd,(struct sockaddr *)&local,sizeof(local));
if(status<0) {
printf("Error binding socket: %s\n",strerror(errno));
goto fin;
}
/* listen socket */
status=listen(sd,5);
if(status<0) {
printf("Error listening socket: %s\n",strerror(errno));
goto fin;
}
/* accept connection */
sd2=accept(sd,0,0);
if(sd2<0) {
printf("Error accepting socket: %s\n",strerror(errno));
goto fin;
}
/* read data */
p=(char *)&msg;
ix=0;
while((len=recv(sd2,p+ix,sizeof(msg)-ix,0))>0) {
ix=ix+len;
}
/* swap bytes on little endian system like x86 PC's */
swap((char *)&msg.a,sizeof(msg.a));
swap((char *)&msg.b,sizeof(msg.b));
swap((char *)&msg.c,sizeof(msg.c));
swap((char *)&msg.d,sizeof(msg.d));
/* print data read */
printf("%d %d %f %f %s\n",msg.a,msg.b,msg.c,msg.d,msg.e);
fin:
/* close sockets */
closesocket(sd2);
closesocket(sd);
/* windows specifik */
WSACleanup();
return 0;
}
import java.io.*;
import java.net.*;
public class Client {
private final static byte ZERO = 0;
private Socket s;
private OutputStream os;
private DataOutputStream dos;
public Client() {
try {
s = new Socket("localhost",12345);
os = s.getOutputStream();
dos = new DataOutputStream(os);
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void sendmsg(short a,int b,float c,double d, String e) {
try {
dos.writeShort(a);
dos.writeInt(b);
dos.writeFloat(c);
dos.writeDouble(d);
dos.write(e.getBytes("ISO-8859-1"));
dos.writeByte(ZERO);
dos.flush();
os.flush();
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Client cli = new Client();
cli.sendmsg((short)123,321,(float)123.456,456.123,"ABCD");
}
}
Hvis ikke C koden compiled med packed struct (/Zp1 iVisual C++) så skal
Java kode sende passende med nul bytes for at alligne.
Hvis C kode ikke har mulighed for at swappe bytes, så skal Java koden
gøre det.
Jeg tror at jeg har noget kode til det liggende.