Forum: Ruby C++ DLL example

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
52a177e9dbd3e614825aabc4e45f8cd6?d=identicon&s=25 Mark Volkmann (Guest)
on 2006-03-10 22:20
(Received via mailing list)
Can someone point me to a simple example of calling a C++ function from
Ruby?
I know how to do it with SWIG, but I'm trying to learn how to do it
without SWIG.
I'd like to do this under Windows and have the C++ code in a DLL.
No Windows APIs will be invoked. I just want to do something simple in
C++ like this

static void greet(const string& name) {
  cout << "Hello " << name << endl;
}

and invoke the greet function from Ruby.

I know how to build a DLL using VC++ 8.
I suspect the issue is that I don't have the right setup in my .cpp
file.
Ce60c4f78a63b0695e4dafc4bd7964f7?d=identicon&s=25 Lou Vanek (Guest)
on 2006-03-11 00:57
(Received via mailing list)
The way I do it is to make sure all entry points in the C++ file are
extern "C"
and create a C wrapper file that calls the C++ funcs which have C
linkage.
Then I run extconf.rb for this wrapper file to create a Ruby extension
makefile.
I picked most of this up from Pickax I, "Extending Ruby."

Also, for some reason I cannot fathom, I had to replace all C++ I/O with
C I/O
routines. After doing that, I was able to compile the C++ file, then
compile the
C extension and properly link everything together as long as I
remembered to add
-lstdc++ as a link option. I always link to either a .a or a .o so I
don't know
how well this applies to a dll.

This was all done with Windows XP / Cygwin / gcc, so my particulars
probably do
not apply to your situation, but the overall plan of attack could be
applied.

BTW, you wont be able to link to a 'static' function. It would be better
to
rewrite it like this:

.cpp file:
extern "C" void greet(char *name) {
    // C++ stuff here

    printf( "Hello %s\n", name );
}

and then I would create a standard .c wrapper file for this, where the
Ruby extension initialization code is put.
A9c4658e9e475e13d790ae419acf01b6?d=identicon&s=25 Simon Kröger (Guest)
on 2006-03-11 12:12
(Received via mailing list)
Hi Mark,

it's not that hard, your cpp file should/could look like this:

---------------------------------------------------------------------
#include "ruby.h"
#include <string>
#include <iostream>

using namespace std;

static void greet(const string& name) {
  cout << "Hello " << name << endl;
}

static VALUE rb_greet(VALUE self, VALUE name){
  greet(STR2CSTR(name));
  return Qnil;
}

void Init_RubyDll() {
  rb_define_global_function("greet", (VALUE(*)(ANYARGS))rb_greet, 1);
}
---------------------------------------------------------------------

Add this to a new dll project, add the path to ruby.h to the project
settings and link against msvcrt-ruby18.lib.

Finally you have to export the Init_XXX (XXX has to be equal to the name
of your Dll) function. I usually add a /EXPORT:Init_RubyDll to the
command line options of the linker.

After doing so i could execute

C:\>ruby -e "require 'RubyDll'; greet 'Mark '"
Hello Mark

Hope that helps.

cheers

Simon

p.s.: one gotcha left: The ruby in the one-click-installer is compiled
with vc6, linking to libs from another version might be risky.

Mark Volkmann schrieb:
Aa575b7606897a056f073f0f148804dd?d=identicon&s=25 Gareth Reeves (reevesg)
on 2006-03-11 14:57
Mark Volkmann wrote:
> Can someone point me to a simple example of calling a C++ function from
> Ruby?
> I know how to do it with SWIG, but I'm trying to learn how to do it
> without SWIG.
> I'd like to do this under Windows and have the C++ code in a DLL.
> No Windows APIs will be invoked. I just want to do something simple in
> C++ like this
>
> static void greet(const string& name) {
>   cout << "Hello " << name << endl;
> }
>
> and invoke the greet function from Ruby.
>
> I know how to build a DLL using VC++ 8.
> I suspect the issue is that I don't have the right setup in my .cpp
> file.

I had a question on C++ extensions that contained some code examples.
Its here http://www.ruby-forum.com/topic/57404#new.

Gareth
52a177e9dbd3e614825aabc4e45f8cd6?d=identicon&s=25 Mark Volkmann (Guest)
on 2006-03-12 16:02
(Received via mailing list)
Thanks for the detailed instructions Simon!

I'm trying to build my DLL with Visual C++ 2005 Express Edition which
is free. I saw your warning about the possibility that this won't work
because the one-click installer is compiled with VC6. I'm not able to
get to the point to test that though. I'm getting a compile error that
says win32.h needs windows.h and it can't find that. I searched my
entire hard drive for windows.h and only found one under my cygwin
directory. I don't want to use that one because I want to find a
solution that doesn't assume cygwin is installed. Any idea why it's
looking for windows.h and where it should be?
This topic is locked and can not be replied to.