From: Michael Neumann Date: 2007-09-22T17:27:20+09:00 Subject: Re: CplusRuby - Gluing C and Ruby Konrad Meyer schrieb: > Quoth Konrad Meyer: >> Quoth Daniel Berger: >>> On Sep 21, 1:01 pm, Michael Neumann wrote: >>>> Hi all, >>>> >>>> I am proud to announce my latest project called CplusRuby. >>>> Below I pasted it's README for further explanation. >>>> Alternatively read the following blog article: >>>> >>>> http://www.ntecs.de/blog/articles/2007/09/21/cplusruby-gluing-c-and-ruby >>> >>> >>> First patch! >>> >>> C:\Documents and Settings\djberge\My Documents\My Downloads\Ruby>diff - >>> u cplusruby.orig cplusruby.rb >>> --- cplusruby.orig Fri Sep 21 15:50:38 2007 >>> +++ cplusruby.rb Fri Sep 21 15:49:04 2007 >>> @@ -11,6 +11,10 @@ >>> # >>> # Implements a simple ordered Hash >>> # >>> +require 'rbconfig' >>> +require 'win32/process' if RUBY_PLATFORM.match('mswin') >>> +include Config >>> + >>> class OHash < Hash >>> def []=(k, v) >>> @order ||= [] >>> @@ -146,20 +150,28 @@ >>> dir = File.dirname(file) >>> mod, ext = base.split(".") >>> >>> + make = RUBY_PLATFORM.match('mswin') ? 'nmake' : 'make' >>> + >>> File.open(file, 'w+') {|f| f << self.generate_code(mod) } >>> Dir.chdir(dir) do >>> - system("make clean") >>> + system("#{make} clean") >>> + >>> pid = fork do >>> require 'mkmf' >>> $CFLAGS = cflags >>> $LIBS << (" " + libs) >>> create_makefile(mod) >>> - exec "make" >>> + exec "#{make}" >>> end >>> _, status = Process.waitpid2(pid) >>> - raise if status.exitstatus != 0 >>> + >>> + if RUBY_PLATFORM.match('mswin') >>> + raise if status != 0 >>> + else >>> + raise if status.exitstatus != 0 >>> + end >>> end >>> - require "#{dir}/#{mod}.so" >>> + require "#{dir}/#{mod}." + CONFIG['DLEXT'] >>> end >>> >>> def self.generate_code_for_class >>> >>> Mostly fixes MS Windows issues, but the DLEXT bit also fixes platforms >>> that don't generate .so files (OS X, HP-UX). >>> >>> Regards, >>> >>> Dan >> Does the C->ruby mapping map between char * and Strings? >> >> Thanks, >> -- >> Konrad Meyer http://konrad.sobertillnoon.com/ > > Okay, so I have added the following to DEFAULT_OPTIONS: > > :int => { > :default => '0', > :ctype => 'int %s', > :ruby2c => '(int)NUM2INT(%s)', > :c2ruby => 'INT2NUM(%s)'}, > > :char_p => { > :default => '""', > :ctype => 'char *%s', > :ruby2c => 'StringValuePtr(%s)', > :c2ruby => 'rb_str_new2(%s)'} > > My code is like this: > > #---------------------start > > require 'cplusruby' > > class BankAccount < CplusRuby > property :balance, :int > property :name, :char_p > > method_c :withdraw, %{int dollars}, %{ > if (dollars <= selfc->balance){ > selfc->balance -= dollars; > return true; I think you shouldn't return "true" here. At least it's not indended, as the withdraw function is "void". > } > } > > def initialize > end > end > > CplusRuby.evaluate("foo.c", "-Os", "") > > n = BankAccount.new > puts n.balance > puts n.name > > #---------------------end > > When I run it with ruby I get a whole bunch of errors stemming from > the fact that it generates C code that uses a type called > "BankAccount" without defining it anywhere (struct BankAccount is > defined though). I think C does not yet work. Try C++ :) CplusRuby.evaluate("foo.cc" ...) But it should be easy to fix, by adding a "typedef struct", and "VALUE(*)()" instead of "VALUE (*)(...)". Ah, and returns values are not yet implemented. Nevertheless you can assign to a property and use it as a return value. Thanks, Michael