[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] call Chicken Scheme from C and pass a bytevector
From: |
Claude Marinier |
Subject: |
Re: [Chicken-users] call Chicken Scheme from C and pass a bytevector |
Date: |
Fri, 28 Jun 2013 08:47:09 -0400 (EDT) |
User-agent: |
Alpine 2.02 (DEB 1266 2009-07-14) |
Hi,
After considering your comments (Dan & Felix), reading the documents, and
some experimentation, I have a solution.
I decided to use atomic data. I believe the C_BYTEBLOCK_BIT is for the GC
and C_BYTEVECTOR_TYPE is the scheme type. The size is in bytes because it
is a byte vector, right?
struct ipv4_addr_struct {
C_header tag;
u_int8_t octets[4];
};
typedef struct ipv4_addr_struct ipv4_addr;
#define IPv4_ADDR_SIZE ( sizeof(ipv4_addr) - sizeof(C_header) )
static const C_header IPv4_ADDR_TAG
= IPv4_ADDR_SIZE | C_BYTEBLOCK_BIT | C_BYTEVECTOR_TYPE;
struct ipv6_addr_struct {
C_header tag;
u_int16_t words[8];
};
typedef struct ipv6_addr_struct ipv6_addr;
#define IPv6_ADDR_SIZE ( sizeof(ipv6_addr) - sizeof(C_header) )
static const C_header IPv6_ADDR_TAG
= IPv6_ADDR_SIZE | C_BYTEBLOCK_BIT | C_BYTEVECTOR_TYPE;
It is used like this. There may be a better way to handle the casting.
saddr_o = C_alloc( IPv4_ADDR_SIZE );
saddr_s = (ipv4_addr *)saddr_o;
saddr_s->tag = IPv4_ADDR_TAG;
memcpy( saddr_s->octets, saddr, sizeof(saddr) );
After that, I put it and the destination address in a regular vector along
with the other packet info.
The scheme packet processing code changed very little: it now uses
blob->u8vector (blob->u16vector for IPv6).
(define-external (process_packet (scheme-object packet)) int
(let ((eth-type (vector-ref packet 0)))
(case eth-type
[(#x0800) ; IPv4
(let ((addr1 (blob->u8vector (vector-ref packet 1)))
(addr2 (blob->u8vector (vector-ref packet 2)))
(proto (vector-ref packet 3)))
It has been running for a while and seems OK. More testing will follow.
Thanks.
--
Claude Marinier
On Fri, 28 Jun 2013, Felix wrote:
Actually, the bytes should probably be allocated in the structure,
right?
struct ipv4_addr_struct {
C_header tag;
uint8_t octets[4];
};
typedef struct ipv4_addr_struct ipv4_addr;
static const C_header BTREE_TAG =
((sizeof(ipv4_addr) - sizeof(C_header)) /
sizeof(C_word)) | C_BYTEVECTOR_TYPE;
This would be a "blob" (or bytevector), right.
cheers,
felix