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.
···
--
R. Mark Volkmann
Partner, Object Computing, Inc.
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.
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.
--
R. Mark Volkmann
Partner, Object Computing, Inc.
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:
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.
--
R. Mark Volkmann
Partner, Object Computing, Inc.
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
···
--
Posted via http://www.ruby-forum.com/.
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?
···
On 3/11/06, Simon Kröger <SimonKroeger@gmx.de> wrote:
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:
> 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.
>
> --
> R. Mark Volkmann
> Partner, Object Computing, Inc.
>
>
--
R. Mark Volkmann
Partner, Object Computing, Inc.