From 3bd7404423c8a89297b52ff9496fa10b86d64046 Mon Sep 17 00:00:00 2001 From: ttate Date: Thu, 11 Apr 2002 08:07:01 +0000 Subject: [PATCH] Add DL::Importable::Internal::Struct#alloc. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2360 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/dl/lib/dl/struct.rb | 13 +++-- ext/dl/sample/libc.rb | 110 ++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 69 deletions(-) diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb index 57703801a6..faa1377c51 100644 --- a/ext/dl/lib/dl/struct.rb +++ b/ext/dl/lib/dl/struct.rb @@ -74,14 +74,19 @@ module DL return @names end - def new(size = nil) + # ptr must be a PtrData object. + def new(ptr) + ptr.struct!(@tys, *@names) + mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) + return mem + end + + def alloc(size = nil) if( !size ) size = @size end ptr = DL::malloc(size) - ptr.struct!(@tys, *@names) - mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) - return mem + return new(ptr) end def parse(contents) diff --git a/ext/dl/sample/libc.rb b/ext/dl/sample/libc.rb index c88fc687f2..cb16aa043f 100644 --- a/ext/dl/sample/libc.rb +++ b/ext/dl/sample/libc.rb @@ -1,64 +1,42 @@ -require 'dl' +require "dl/import" +require "dl/struct" module LIBC + extend DL::Importable + begin - LIB = DL.dlopen('libc.so.6') - rescue RuntimeError - LIB = DL.dlopen('libc.so.5') + dlload "libc.so.6" + rescue + dlload "libc.so.5" end - SYM = { - :atoi => LIB['atoi', 'IS'], - :isdigit => LIB['isdigit', 'II'], - } + extern "int atoi(char*)" + extern "ibool isdigit(int)" + extern "int gettimeofday(struct timeval *, struct timezone *)" + extern "char* strcat(char*, char*)" + extern "FILE* fopen(char*, char*)" + extern "int fclose(FILE*)" + extern "int fgetc(FILE*)" + extern "int strlen(char*)" + extern "void qsort(void*, int, int, void*)" - def atoi(str) - r,rs = SYM[:atoi].call(str) - return r + def str_qsort(ary, comp) + len = ary.length + r,rs = qsort(ary, len, DL.sizeof('P'), comp) + return rs[0].to_a('S', len) end - def isdigit(c) - r,rs = SYM[:isdigit].call(c) - return (r != 0) - end + Timeval = struct [ + "long tv_sec", + "long tv_usec", + ] + + Timezone = struct [ + "int tz_minuteswest", + "int tz_dsttime", + ] end -module LIBC - SYM[:strcat] = LIB['strcat', 'SsS'] - def strcat(str1,str2) - r,rs = SYM[:strcat].call(str1 + "\0#{str2}",str2) - return rs[0] - end -end - -module LIBC - SYM[:fopen] = LIB['fopen', 'PSS'] - SYM[:fclose] = LIB['fclose', '0P'] - SYM[:fgetc] = LIB['fgetc', 'IP'] - - def fopen(filename, mode) - r,rs = SYM[:fopen].call(filename, mode) - return r - end - - def fclose(ptr) - SYM[:fclose].call(ptr) - return nil - end - - def fgetc(ptr) - r,rs = SYM[:fgetc].call(ptr) - return r - end -end - -module LIBC - SYM[:strlen] = LIB['strlen', 'IP'] - def strlen(str) - r,rs = SYM[:strlen].call(str) - return r - end -end $cb1 = DL.set_callback('IPP', 0){|ptr1, ptr2| str1 = ptr1.ptr.to_s @@ -66,19 +44,21 @@ $cb1 = DL.set_callback('IPP', 0){|ptr1, ptr2| str1 <=> str2 } -module LIBC - SYM[:qsort] = LIB['qsort', '0aIIP'] - def qsort(ary, comp) - len = ary.length - r,rs = SYM[:qsort].call(ary, len, DL.sizeof('P'), comp) - return rs[0].to_a('S', len) - end -end +p LIBC.atoi("10") -include LIBC +p LIBC.isdigit(?1) -p atoi("10") -p isdigit(?1) -p isdigit(?a) -p strcat("a", "b") -p qsort(["a","c","b"],$cb1) +p LIBC.isdigit(?a) + +p LIBC.strcat("a", "b") + +ary = ["a","c","b"] +ptr = ary.to_ptr +LIBC.qsort(ptr, ary.length, DL.sizeof('P'), $cb1) +p ptr.to_a('S', ary.length) + +tv = LIBC::Timeval.alloc +tz = LIBC::Timezone.alloc +LIBC.gettimeofday(tv, tz) + +p Time.at(tv.tv_sec)