Java'da pointer tarzında bir yapı mevcut mu?

Başlatan NaMcHo, 22 Eylül 2013, 17:23:33

NaMcHo

Merhabalar,

FTDI232 chipi ile STM32F3 arasında veri alışverişi yapabiliyorum ancak bir durum var çözemediğim.
C (STM32F3'den yollanan veri) tarafında şu şekilde bir veri yapım var:
struct _FTDI_st{
	int32_t kimlik;
	char ob1;
	int16_t ob2;
	char ob3;
	char bilgi[5];
};


Bu veriyi doğru bir şekilde Java tarafına yollayıp byte tipinde bir diziye doğru bir şekilde alabiliyorum.
Java tarafında ise bir class tanımladım şu şekilde
public class FtdiAlinan {
	int kimlik;
	byte ob1;
	short ob2;
	byte ob3;
	byte[] bilgi;
	
	FtdiAlinan(int bilgiUzn){
		bilgi = new byte[bilgiUzn];
	}
	
	public void ByteToStruct(byte[] b){
		
	}
}


Eğer javada pointer kullanımı olsaydı basit bir şekilde aldığım verileri bu fieldlara yazabilecektim.
Yapmak istediğim şu şekilde:
char *recieverPtr;
 char stmBytes[];
 struct _FTDI_st ftdiR;

	recieverPtr = ((char *)&ftdiR.kimlik);
	size = sizeof(ftdiR);
	for(count = 0; count < size; count++){
		(*recieverPtr) = stmBytes[count];
		recieverPtr = recieverPtr + 1;
	}

Bu tarz birşeyle verilerimi almak istiyorum bunu nasıl yapabilirim Javada?

Tagli

Java'da C'deki gibi bir pointer mantığı yok. Ama nesneleri tutan değişkenler referans değişkenleri olarak adlandırılıyor ve pointer gibi çalışıyorlar (ya da C++'daki referanslar gibi).

Bahsettiğin şey, Java ile uğraştığım dönemde (ki bayadır uğraşmıyorum, 2009'dan beri) hiç lazım olmamıştı, o yüzden çözümü bilmiyorum. Ama olay "serialization" denilen konuyla ilgili gibi gözüküyor. Java'da bu şekilde bir nesneyi seri byte'lar haline getirip dosyaya yazabiliyor ve gerektiğinde buradan okuyarak eski nesneyi elde edebiliyorduk, ki bu halini kullanmıştım.

Burada ByteArrayOutputStream diye bir şeyden bahsetmiş. Belki işe yarar.
Gökçe Tağlıoğlu

cicjoe

Hocam, Java'da pointer olsa da yaptiginiz islem dogru sonuc vermeyecektir tahminimce, cunku C ve Java'nin yapilari tutus bicimleri birbirinden farkli..
Ornegin C#'ta hangi degiskenin nerde olmasini belirtmek istiyorsaniz, asagidaki gibi attribute'ler kullaniliyor.. Veya LayoutKind.Sequential derseniz, tanimlama sirasina gore yerlestirecektir, ancak belirtmezseniz boyle bir durum soz konusu değil..

[StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
   public class MySystemTime
   {
      [FieldOffset(0)]public ushort wYear;
      [FieldOffset(2)]public ushort wMonth;
      [FieldOffset(4)]public ushort wDayOfWeek;
      [FieldOffset(6)]public ushort wDay;
      [FieldOffset(8)]public ushort wHour;
      [FieldOffset(10)]public ushort wMinute;
      [FieldOffset(12)]public ushort wSecond;
      [FieldOffset(14)]public ushort wMilliseconds;
   }

NaMcHo

#3
Anahtar kelime serileştirmeymiş bu gibi durumlar için.

jd.open(0);
					jd.read(alinan);				
					
					try {
						ByteArrayInputStream bais = new ByteArrayInputStream(alinan);
						InputStream in = new ObjectInputStream(bais);
						ObjectInputStream ois = new ObjectInputStream(in);
						recived = (FtdiAlinan)ois.readObject();
						bais.close();
						in.close();
						ois.close();
					} catch (Exception e) {
						// TODO: handle exception
						System.out.println("Serilestirme esnasında sorun...");
					}


Şöyle birşey yazdım nettende bakarak ancak hep exception fırlatıyor...

run fonksiyonunun tamamı:
public void run(){
			// TODO Auto-generated method stub
			byte[] alinan = new byte[13];
			FtdiAlinan recived = new FtdiAlinan(5);
			
			while(running){
				
				try {
					//Ftdi okuma 
					jd.open(0);
					jd.read(alinan);				
					
					try {
						ByteArrayInputStream bais = new ByteArrayInputStream(alinan);
						InputStream in = new ObjectInputStream(bais);
						ObjectInputStream ois = new ObjectInputStream(in);
						recived = (FtdiAlinan)ois.readObject();
						bais.close();
						in.close();
						ois.close();
					} catch (Exception e) {
						// TODO: handle exception
						System.out.println("Serilestirme esnasında sorun...");
					}
					
					
					for (int i = 0; i < alinan.length; i++) {
						System.out.print((char)alinan[i] + " ");
					}
					System.out.println();
					txtAlinan.append(recived.kimlik + " " + recived.ob1 + " " + recived.ob2 + " " + recived.ob3 + '\n');
					for (int i = 0; i < recived.bilgi.length; i++) {
						txtAlinan.append(String.valueOf((char)recived.bilgi[i]));
					}
					txtAlinan.append('\n' + " ");
					jd.close();
					
					//System.out.println(alinan.toString());
					//Bekleme
					Thread.sleep(100);
					
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("Ftdi aliminda Kesme geldi 10ms'lik beklmede...");
				}
			}
		}

NaMcHo

#4
Serileştirme ile ilgili bir uygulama yaptım ve sonuç hiç beklediğim gibi değil. Problem gözümde iyice büyüdü.
FtdiAlinan sınıfının field'larına ilk değerlerini atadım ve byte olarak bir diziye yazdım sonuç aşağıdaki gibi.
package nazimyildiz.com;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class SerilestirmeDemo {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		FtdiAlinan ftdi = new FtdiAlinan(5);
		ftdi.kimlik = 0x00001;
		ftdi.ob1 = 0x55;
		ftdi.ob2 = 567;
		ftdi.ob3 = 'a';
		ftdi.bilgi[0] = 'K';
		ftdi.bilgi[1] = 'o';
		ftdi.bilgi[2] = 'd';
		ftdi.bilgi[3] = '1';
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutput out = null;
		try {
			out = new ObjectOutputStream(baos);
			out.writeObject(ftdi);
			byte[] ftdiBytes = baos.toByteArray();
			System.out.println("Uzunuluk: " + ftdiBytes.length);
			
			for (int i = 0; i < ftdiBytes.length; i++) {
				System.out.println(ftdiBytes[i]);
			}
		} catch (Exception e) {
			// TODO: handle exception
			
			System.out.println(e.getMessage());
		}
		finally{
			out.close();
			baos.close();
		}
		
		
	}

}


FtdiAlinan sınıfıda şu şekilde...
package nazimyildiz.com;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class FtdiAlinan implements Serializable {
	public int kimlik;
	public byte ob1;
	public short ob2;
	public byte ob3;
	public byte[] bilgi;
	
	FtdiAlinan(int bilgiUzn){
		bilgi = new byte[bilgiUzn];
	}
}


Uygulamayı çalıştırdığımda çıktı şu şekilde oluyor:
Uzunuluk: 123
-84
-19
0
5
115
114
0
26
110
97
122
105
109
121
105
108
100
105
122
46
99
111
109
46
70
116
100
105
65
108
105
110
97
110
-122
101
-127
30
-44
52
5
-99
2
0
5
73
0
6
107
105
109
108
105
107
66
0
3
111
98
49
83
0
3
111
98
50
66
0
3
111
98
51
91
0
5
98
105
108
103
105
116
0
2
91
66
120
112
0
0
0
1
85
2
55
97
117
114
0
2
91
66
-84
-13
23
-8
6
8
84
-32
2
0
0
120
112
0
0
0
5
75
111
100
49
0


En son 5 satır, bilgi dizisinde tutulan veri yani "Kod1" ancak fazladan çok fazla byte var ve bana lazım olan diğer field'ların nerelerde olduğunu öğrenmek, angarya bir iş gibi gözüküyor. Serileştirmeyi yaptıkdan sonra field'larımın byte'larının başladğı index numaralarını bir şekilde biliyor olsam oldukça basit olacak.

Bu serileştirmenin olayı var olan bir nesnenin(field'larına atama yapılmış) yedeklenip daha sonra kullanılabilmesine dayanıyor... Benim amacım nesne kalıbım var ama içi boş bunu doldurmak sanırsam serileştirme ile C'deki gibi kolay bir şekilde bu surunu çözemeyeceğim (Java'da henüz yeniyim o yüzden sorunu çözebilmem için anahtar kelimelere ihtiyacım var, google'a ne yazacağımı bilemedim, bayada birşey yazıpda arama yaptım ancak henüz sonuç yok)...

Alternatif arayışlarım sürüyor.

cicjoe söylediğinide bu uygulama çıktısında görmüş oldum, field'lar peş peşe sıralanmıyormuş Java'da anlaşılan, yani ilk başta vermiş olduğum C örneğindeki gibi bir yöntem ilede bu iş olmayacakmış.

cicjoe

Hocam, XML veya JSON ile platform bagimsiz obje transferi yapabilirsiniz.