Estructuras dentro de estructuras, y ademas con arrays...

Post Reply
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Estructuras dentro de estructuras, y ademas con arrays...

Post by JmGarcia »

Otra vez a vueltas con las estructuras...

Tengo este codigo VB

Code: Select all

Const MAX_IP = 5

Type IPINFO
    dwAddr As Long   ' IP address
    dwIndex As Long '  interface index
    dwMask As Long ' subnet mask
    dwBCastAddr As Long ' broadcast address
    dwReasmSize  As Long ' assembly size
    unused1 As Integer ' not currently used
    unused2 As Integer '; not currently used
End Type

Type MIB_IPADDRTABLE
    dEntrys As Long   'number of entries in the table
    mIPInfo(MAX_IP) As IPINFO  'array of IP address entries
End Type

Type IP_Array
    mBuffer As MIB_IPADDRTABLE
    BufferLen As Long
End Type
Como lo paso a FWH+XHB.
Solo he hecho esto:

Code: Select all

#define MAX_IP 5
STRUCT IPINFO
    MEMBER dwAddr      AS LONG // IP address
    MEMBER dwIndex     AS LONG // interface index
    MEMBER dwMask      AS LONG // subnet mask
    MEMBER dwBCastAddr AS LONG // broadcast address
    MEMBER dwReasmSize AS LONG // assembly size
    MEMBER unused1     As WORD // not currently used
    MEMBER unused2     AS WORD // not currently used
ENDSTRUCT
Pero no se seguir...
Hay un array y una estructura dentro de otra...
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Post by JmGarcia »

¡¡¡ Socorro !!!

Ya se que soy "muy rarito" con mis desarrollos pero necesito una solución al mensaje anterior de estructras.

Gracias.
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Post by JmGarcia »

JmGarcia wrote:Ya se que soy "muy rarito" con mis desarrollos pero necesito una solución al mensaje anterior de estructras.
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

JM,

Define y usa esas estructuras en lenguaje C, no desde el PRG.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

De hecho desde C ni siquiera tienes que definirlas ya que estan definidas en iprtrmib.h
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Post by JmGarcia »

Antonio Linares wrote:Define y usa esas estructuras en lenguaje C, no desde el PRG.
Antonio Linares wrote:De hecho desde C ni siquiera tienes que definirlas ya que estan definidas en iprtrmib.h
Quieres decir que use algo asi...

Code: Select all

#include "FiveWin.Ch"
#include "CStruct.ch" 

typedef struct _IP_ADDR_STRING {;
  LONG Next;
  CHAR IpAddress[16];
  CHAR IpMask[16];
  LONG  Context;
} IP_ADDR_STRING, *PIP_ADDR_STRING;

FUNCTION main()
public AddrStr:=(struct IP_ADDR_STRING)
.../...
return nil
Respecto a este tipo de definición de estructuras tengo una duda.
Asi como el tamaño es IP_ADDR_STRING:sizeOf() igual que usando las otras tipoas de estructuras me hace falta saber cual es el BUFFER de la estructura.

En las definidas en xHarbour/FW es una DATA oEstructura:cBuffer

Code: Select all

#include "FiveWin.ch"
#include "struct.ch"
#include "exstruc.ch"

function Main()

STRUCT sockaddr
  MEMBER s_family AS _INT
  MEMBER s_port   AS _INT
  MEMBER s_addr   AS LONG
  MEMBER s_zero   AS STRING LEN 8
ENDSTRUCT

sockaddr:s_family:=AF_INET
sockaddr:s_addr  :=inet_addr(m_IpSet)
sockaddr:s_port  :=htons(m_PortSet)
sockaddr:s_zero  :=replicate(chr(0),8)
cTemp:=sockaddr:cBuffer
sendto(SocketNum,Texto,len(Texto),MSG_DONTROUTE,@cTemp,sockaddr_size)
sockaddr:cBuffer:=cTemp

.../...
return nil
¿ Cual es el BUFFER en las tipo "C" ?
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

JM,

No, no me refiero a eso (que además no se puede hacer).

A que función de C de Windows quieres llamar que necesita esas estructuras ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Post by JmGarcia »

Antonio Linares wrote:A que función de C de Windows quieres llamar que necesita esas estructuras ?
Pues muchas de ellas de comunicaciones:

Code: Select all

WSAStartup
WSACleanup
closesocket
socket
setsockopt
getsockopt
htonl
htons
bind
inet_addr
WSAAsyncSelect
recv
recvfrom
send
sendto
WSAGetLastError
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
User avatar
thefull
Posts: 720
Joined: Fri Oct 07, 2005 7:42 am
Location: Barcelona
Contact:

Post by thefull »

Todas estas estan en parte en Fivewin y en la libreria de TIP de Harbour, por lo tanto, ni tan siguiera deberias de preocuparte por las estructuras.

Echale un vistazo a las diferentes clases existentes en [x]Harbour , clase tsockects, thtml, etc..

Si alguna no estuviese, podrias implementarla en C, mucho más simple y mucho mas eficaz, que hacerlo con PRG
Saludos
Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

JM,

Como te comenta Rafa, échale un vistazo a fwh\source\winapi\winsock.c :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Post by JmGarcia »

thefull wrote:...y en la libreria de TIP de Harbour
He mirado la TIP y no me da soluciones, pero siguiendo la pista que me has dado he llegado a funciones de xHarbour de tratamiento multicast.
Pero me encuentro que no me "llenan" del todo en cuanto a posiblidades.

INetDGramBind(<nPort>,[<cIPAddress>],[<lBroadcast>],[<cMulticast>]) --> pSocket
Le falta el poder manejar las subscripciones multicast a gusto de las necesidades.
Asi por ejejmplo solo hace la IP_ADD_MEMBERSHIP para la subscripcion del flujo multicast deseado, pero no la IP_DROP_MEMBERSHIP para anular la subscripcion.
Ademas no maneja el TTL (IP_MULTICAST_TTL) que es el tiempo de vida de la trama (Time To Live).
Necesario el parametro TTL para poder controlar el "alcance" de la "emision" de las tramas multicast.

INetDGramSend(<pSocket>,<cIPAddress>,<nPort>,<cData>,[<nBytes>]) --> nSentBytes
No usa enrutamiento por tablas ARP. Aunque me serviria.

INetDGramRecv(<pSocket>,@<cBuffer>,[<nBytes>]) --> nReceivedBytes
Solo efectua el RECV del Win-API no el recvFROM con lo que si recibimos varias tramas multicast con la misma direccion IP destino y distintos origenes no podremos distingir su origen.
Antonio Linares wrote:Como te comenta Rafa, échale un vistazo a fwh\source\winapi\winsock.c :-)
En cuanto al API-FW veo la falta de parametros que me serián necesarios.

En las funciones de winsock.c comparadas con el API de Windows pienso esto:
WSAStartup no admite párametros, la del WinAPI dos (Version y Buffer)
HTONS es la misma.
INET_ADDR es la misma.
Socket es la misma.
BINDTOPORT menos parametros.
RECV menos parametros y no existe la recvFROM.
SOCKETSEND/SENDBINARY menos parametros y no existe la sendTO.
SETSOCKOPT menos parametros y no existe la GETsockopt.

Yo lo que he hecho es WRAPEAR las funciones del API de Windows, en su mayoria de la wsock32.dll, en las que he dejado todos sus parametros disponibles.

Code: Select all

DLL32 FUNCTION WSAStartup(n AS LONG, pStruct AS LPSTR) AS LONG PASCAL FROM "WSAStartup" LIB "wsock32.dll"
DLL32 FUNCTION WSACleanup() AS LONG PASCAL FROM "WSACleanup" LIB "wsock32.dll"
DLL32 FUNCTION closesocket(af AS LONG) AS WORD PASCAL FROM "closesocket" LIB "wsock32.dll"
DLL32 FUNCTION MemCopy(dest AS LPSTR, src AS LPSTR, cb AS LONG ) AS VOID PASCAL FROM "RtlMoveMemory" LIB "Kernel32.dll"
DLL32 FUNCTION socket(af AS LONG, s_type AS LONG, protocol AS LONG ) AS LONG PASCAL FROM "socket" LIB "wsock32.dll"
DLL32 FUNCTION setsockopt(s AS LONG,level AS LONG,optname AS LONG,optval AS LPSTR,optlen AS LONG) AS LONG PASCAL FROM "setsockopt" LIB "wsock32.dll"
DLL32 FUNCTION getsockopt(s AS LONG,level AS LONG,optname AS LONG,optval AS LPSTR,optlen AS LONG) AS LONG PASCAL FROM "getsockopt" LIB "wsock32.dll"
DLL32 FUNCTION htonl(hostlong AS LONG) AS LONG PASCAL FROM "htonl" LIB "wsock32.dll"
DLL32 FUNCTION htons(hostshort AS LONG) AS WORD PASCAL FROM "htons" LIB "wsock32.dll"
DLL32 FUNCTION bind(s AS LONG, pStruct AS LPSTR,namelen AS LONG) AS LONG PASCAL FROM "bind" LIB "wsock32.dll"
DLL32 FUNCTION inet_addr(cp AS STRING) AS LONG PASCAL FROM "inet_addr" LIB "wsock32.dll"
DLL32 FUNCTION WSAAsyncSelect(s AS LONG, hWnd AS LONG, wMsg AS LONG, lEvent AS LONG) AS LONG PASCAL FROM "WSAAsyncSelect" LIB "wsock32.dll"
DLL32 FUNCTION recv(s AS LONG, Buf AS LPSTR, buflen AS LONG, flags AS LONG) AS LONG PASCAL FROM "recv" LIB "wsock32.dll"
DLL32 FUNCTION recvfrom(s AS LONG, Buf AS LPSTR, buflen AS LONG, flags AS LONG,  addr As sockaddr, i AS LONG) AS LONG PASCAL FROM "recvfrom" LIB "wsock32.dll"
DLL32 FUNCTION send(s AS LONG, Buf AS LPSTR, buflen AS LONG, flags AS LONG) AS LONG PASCAL FROM "send" LIB "wsock32.dll"
DLL32 FUNCTION sendto(s AS LONG, Buf AS LPSTR, buflen AS LONG, flags AS LONG, addr AS LPSTR, i AS LONG) AS LONG PASCAL FROM "sendto" LIB "wsock32.dll"
DLL32 FUNCTION WSAGetLastError() AS LONG PASCAL FROM "WSAGetLastError" LIB "wsock32.dll"
Pero claro, casi todos los parametros AS LPSTR, son punteros a estructuras. Con o que hay que pasarles por referencia el buffer de la estructura.
Me funcionan de maravilla las estructuras del tipo:
#include "struct.ch"
#include "exstruc.ch"
STRUCT sockaddr
MEMBER s_family AS WORD
MEMBER s_port AS WORD
MEMBER s_addr AS LONG
MEMBER s_zero AS STRING LEN 8
ENDSTRUCT

Las tipo "C" me han dado problemas de manejo de buffers y de tipo de datos.
Por eso el poder crear arrays dentro de estructuras y estructuras anidades pero usando estos tipos de FW.
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

JM,

En las funciones en las que no definimos determinados parámetros, normalmente lo hacemos porque se pueden usar valores por defecto de forma satisfactoria.

A lo que me refería es que modifiques source\winapi\winsock.c y asi las funciones esten implementadas en C con lo que tienes total acceso a las estructuras anidadas en C.

Los parámetros para rellenar esas estructuras los puedes enviar a las funciones desde el PRG y desde C asignarlos. Usando el comando de alto nivel DLL FUNCTION no puedes rellenar las estructuras anidadas
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
JmGarcia
Posts: 654
Joined: Mon May 29, 2006 3:14 pm
Location: Madrid - ESPAÑA

Post by JmGarcia »

Antonio Linares wrote:En las funciones en las que no definimos determinados parámetros, normalmente lo hacemos porque se pueden usar valores por defecto de forma satisfactoria.
Entiendo.
Antonio Linares wrote:Los parámetros para rellenar esas estructuras los puedes enviar a las funciones desde el PRG y desde C asignarlos. Usando el comando de alto nivel DLL FUNCTION no puedes rellenar las estructuras anidadas
En fin... empezaremos a pensar "algo" en C.

Aqui un ejejmplo de MULTIcast y de BROADcast hecho con las funciones INetInit, INetClose, INetCleanup, INetDGramBind, INetDGramSend y InetDGram.
Solo que el TTL de la trama multicast es siempre 1 y el de la broadcast es 128.
Quiere esto decir que la trama multicast NO saldra de la subred en la que esta el host, sin embargo la broadcast dara hasta 128 saltos.

Code: Select all

#include "FiveWin.Ch"
FUNCTION main()
public cIPhost:="127.0.0.1",;
       cIPmulticast:="224.10.10.10",;
       cIPbroadcast:="192.10.10.255",;
       nPuertoUDP:=1800,;
       pSocket:=0,nSentBytes:=0,;
       cBufferMulticast:="HOLA SOY UNA TRAMA MULTICAST",;
       cBufferBroadticast:="HOLA SOY UNA TRAMA BROADCAST"
*--- Envia trama MULTIcast
INetInit()
pSocket:=INetDGramBind(nPuertoUDP,cIPhost,.F.,cIPmulticast)
nSentBytes:=INetDGramSend(pSocket,cIPmulticast,nPuertoUDP,cBufferMulticast,len(cBufferMulticast))
INetClose(pSocket)
INetCleanup()
*--- Envia trama BROADcast
INetInit()
pSocket:=InetDGram(.T.)
nSentBytes:=INetDGramSend(pSocket,cIPbroadcast,nPuertoUDP,cBufferBroadticast,len(cBufferBroadticast))
INetClose(pSocket)
INetCleanup()
*---
return nil
Un poco de culturilla general:
Un poco de informacion sobre el TTL (TimeToLive): http://es.wikipedia.org/wiki/Tiempo_de_ ... %A1tica%29
Sobre multicast: http://es.wikipedia.org/wiki/Broadcast_ ... lticast.29
Sobre broadcast: http://es.wikipedia.org/wiki/Broadcast_%28Sobre_IP%29
Mi abuelo decía: Los aviones vuelan porque Dios quiere, y los helicópteros ni Dios sabe porque vuelan.
FWH 16.02, xHarbour 1.2.3, Harbour 3.2.0, WorkShop 4.5, AJ Make 0.30, Borlan BCC 7.00, VisualStudio 2013
Post Reply