Jon,

Thanks. This works and, you are right, the declspecs aren't needed since the
makefile specifies what to export.

This seems like the best solution since the compile flags are set
automatically.

Thanks again and to everyone else who responded.

Al

"Jon Israelson" <jisraelson / computer.org> wrote in message
news:v0tY7.9359$4d5.117510 / rwcrnsc54...
> I successfully built and ran a slightly modified version of your code
using
> VC++ 6 with the mswin32 build of Ruby 1.6.6 (which I built from the Ruby
> sources).  The steps that I followed were:
>
> 1.  created the C source file Test.c
> 2.  created the extension config file extconf.rb
> 3.  ran 'ruby extconf.rb' to generate a Makefile.  This is probably the
key
> to solving your problem as it takes care of all the compiler/linker/export
> settings;  I haven't ever tried to build using a VC++ project.
> 4.  ran nmake.  The resulting file is named Test.so (just a DLL with a
> different extension).
> 5.  tested the extension with irb
>
> The sources used and a trace of the irb session are listed below.  Hope
this
> helps.
>
> - Jon
>
> ************************************
> d:\temp\Test.c
> --> commented out the declspecs and renamed write to __write to prevent a
> name collision in io.h
> ************************************
>
> #include "ruby.h"
> #include <stdio.h>
>
> // __declspec(dllexport) void Init_Test(void);
>
> static VALUE t_init(VALUE self) {
>     VALUE arr;
>     arr = rb_ary_new();
>     rb_iv_set(self, "@arr", arr);
>     return self;
> }
>
> static VALUE t_add(VALUE self, VALUE anObject) {
>     VALUE arr;
>
>     arr = rb_iv_get(self, "@arr");
>     rb_ary_push(arr, anObject);
>     return arr;
> }
>
> VALUE cTest;
>
> void __write(char* pStr);
>
> file://__declspec(dllexport) void Init_Test(void) {
> void Init_Test(void) {
>     __write("At A");
>     cTest = rb_define_class("Test", rb_cObject);
>     __write("At B");
>     rb_define_method(cTest, "initialize", t_init, 0);
>     __write("At C");
>     rb_define_method(cTest, "add", t_add, 1);
>     __write("At D");
> }
>
> /* For debugging */
> void __write(char* pStr) {
>     FILE *fp = fopen("test.log", "a");
>     fprintf(fp, pStr);
>     fprintf(fp, "\n");
>     fclose(fp);
> }
>
> ************************************
> d:\temp\extconf.rb
> ************************************
>
> require 'mkmf'
> create_makefile("Test")
>
> ************************************
> d:\temp\Makefile created by running 'ruby extconf.rb'
> ************************************
>
> SHELL = /bin/sh
>
> #### Start of system configuration section. ####
>
> srcdir = .
> topdir = $(rubylibdir)/$(arch)
> hdrdir = $(rubylibdir)/$(arch)
> VPATH = $(srcdir)
>
> CC = cl
>
> CFLAGS   = -DIMPORT -nologo -DNT=1 -Zi -MD -O2b2xg- -G5
> CPPFLAGS = -I$(hdrdir) -I$(srcdir) -I$(prefix)/include
> CXXFLAGS = $(CFLAGS)
> DLDFLAGS = $(CFLAGS)
> LDSHARED = cl -LD
> LIBPATH = $(exec_prefix)/lib
>
> RUBY_INSTALL_NAME = ruby
> RUBY_SO_NAME = mswin32-ruby16
> arch = i586-mswin32
> ruby_version = 1.6
>
> DESTDIR = c:
> prefix = $(DESTDIR)/ruby
> exec_prefix = $(prefix)
> libdir = $(exec_prefix)/lib
> rubylibdir = $(libdir)/ruby/$(ruby_version)
> archdir = $(rubylibdir)/$(arch)
> sitedir = $(prefix)/lib/ruby/site_ruby
> sitelibdir = $(sitedir)/$(ruby_version)
> sitearchdir = $(sitelibdir)/$(arch)
> target_prefix =
>
> #### End of system configuration section. ####
>
> LOCAL_LIBS =  -link /INCREMENTAL:no /EXPORT:Init_$(TARGET)
> LIBS = $(RUBY_SO_NAME).lib
> OBJS = Test.obj
>
> TARGET = Test
> DLLIB = $(TARGET).so
>
> RUBY = ruby
> RM = $(RUBY) -rftools -e "File::rm_f(*ARGV.map{|x|Dir[x]}.flatten.uniq)"
>
> EXEEXT = .exe
>
> all:  $(DLLIB)
>
> clean:;  @$(RM) *.obj *.so *.sl *.a $(DLLIB)
>   @$(RM) $(TARGET).lib $(TARGET).exp $(TARGET).ilk *.pdb $(CLEANFILES)
>
> distclean: clean
>   @$(RM) Makefile extconf.h conftest.* mkmf.log
>   @$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
>
> realclean: distclean
>
> install: $(archdir)$(target_prefix)/$(DLLIB)
>
> site-install: $(sitearchdir)$(target_prefix)/$(DLLIB)
>
> $(archdir)$(target_prefix)/$(DLLIB): $(DLLIB)
>  @$(RUBY) -r ftools -e 'File::makedirs(*ARGV)' $(rubylibdir)
> $(archdir)$(target_prefix)
>  @$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0555, true)'
> $(DLLIB) $(archdir)$(target_prefix)/$(DLLIB)
>
> $(sitearchdir)$(target_prefix)/$(DLLIB): $(DLLIB)
>  @$(RUBY) -r ftools -e 'File::makedirs(*ARGV)'
> $(sitearchdir)$(target_prefix)
>  @$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0555, true)'
> $(DLLIB) $(sitearchdir)$(target_prefix)/$(DLLIB)
>
>
> {$(srcdir)}.c.obj:
>  $(CC) $(CFLAGS) -I$(<D) $(CPPFLAGS) -c $(<:/=\)
> .c.obj:
>  $(CC) $(CFLAGS) -I$(<D) $(CPPFLAGS) -c $(<:/=\)
>
> {$(srcdir)}.cc{}.obj:
>  $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\)
> .cc.obj:
>  $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\)
> {$(srcdir)}.cpp{}.obj:
>  $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\)
> .cpp.obj:
>  $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\)
> {$(srcdir)}.cxx{}.obj:
>  $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\)
> .cxx.obj:
>  $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\)
> $(DLLIB): $(OBJS)
>  set LIB=$(LIBPATH:/=\);$(LIB)
>  $(LDSHARED) $(DLDFLAGS) -o $(DLLIB) $(OBJS) $(LIBS) $(LOCAL_LIBS)
>
>
> ************************************
> irb output
> ************************************
>
> irb(main):001:0> require './Test'
> true
> irb(main):002:0> t = Test.new
> #<Test:0x2ac1e98 @arr=[]>
> irb(main):003:0> t.add("one")
> ["one"]
> irb(main):004:0> t.add("two")
> ["one", "two"]
>
>
>