Created
May 20, 2010 23:35
-
-
Save ashgti/408274 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# old way: | |
func = dlfunc lib, "foo", "vilf" | |
Limited by the string. New types aren't available, and aliasing types doesn't work. Structures are difficult too. | |
# New way: | |
constants: | |
c_void = c void | |
c_char = c int8 | |
c_wchar = c_sint16 or c_int32 # system dependent | |
c_byte = c_sint8 | |
c_ubyte = c_uint8 | |
c_short = c_sint16 | |
c_ushort = c_uint16 | |
c_int = c_long = c_sint32 | |
c_uint = c_ulong = c_uint32 | |
c_longlong = c_sint64 # __int64 or long long int/long | |
c_ulonglong = c_uint64 # unsigned __int64 or unsigned long long int/long | |
c_float # float | |
c_double # double float | |
c_longdouble # long double float system dependent | |
# connivence consts: | |
c_char_p # char * (NUL terminated) string or None | |
c_wchar_p # wchar_t * (NUL terminated) unicode or None | |
c_void_p # void * int/long or None | |
# functions: | |
PMC pointer(PMC type_constant) # finds the pointer value of a constant type | |
PMC byref(PMC ref_value) # finds makes a reference for function calls | |
PMC array(PMC type_constant, INT size) # creates a new array of type_constant type of size length | |
PMC newstruct 'name' | |
INT sizeof(PMC type or value) | |
PMC cast(PMC value, PMC type_constant) | |
# Example: | |
# C Example: | |
struct in_addr | |
{ | |
unsigned long s_addr; | |
}; | |
struct sockaddr_in | |
{ | |
short sin_family; /* must be AF_INET */ | |
u_short sin_port; | |
struct in_addr sin_addr; | |
char sin_zero[8]; /* Not used, must be zero */ | |
}; | |
pin.sin_family = AF_INET; | |
pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; | |
pin.sin_port = htons(PORT); | |
/* grab an Internet domain socket */ | |
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { | |
perror("socket"); | |
exit(1); | |
} | |
/* connect to PORT on HOST */ | |
if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { | |
perror("connect"); | |
exit(1); | |
} | |
# Potential parrot equivalent: | |
$P0 = newstruct 'in_addr' | |
$P0['s_addr'] = c_ulong | |
$P1 = newstruct 'sockaddr_in' | |
$P1['sin_family'] = c_short | |
$P1['sin_port'] = c_ushort | |
$P1['sin_addr'] = $P0 | |
$P1['sin_zero'] = array(c_char, 8) | |
$P2 = new $P1 | |
$P2['sin_family'] = AF_INET # constant defined somewhere else | |
$P3 = pointer('in_addr') | |
$P4 = cast($P123, $P3) # $P123 given defined somewhere else | |
$P2['sin_addr';'s_addr'] = $P4['s_addr'] | |
$P2['sin_port'] = 1234 | |
# return, #param1 ... n | |
$P5 = dlfunc lib, 'socket', c_int , c_int, c_int, c_int | |
$P6 = $P5(AF_INET, SOCK_STREAM, 0) # constants defined elsewhere | |
# connect signature: int connect(int, struct sockaddr *address, socklen_t address_len); socklen_t = int (assuming) | |
$P7 = dlfunc lib, 'connect', c_int, c_int, c_void_p, c_int) | |
$P8 = pointer($P2) | |
$P9 = byref($P2) | |
$I1 = sizeof($P2) | |
$P7($P6, $P9, $I1) # invoke connect(int, struct sockaddr *address, socklen_t address_len) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment