Questions


(Mathieu Bouchard) #1

i am writing a ruby extension in C; i am using Ruby 1.6.7 and Debian 3.0.
here are a few problems i am running into.

  1. requiring a library that does not contain its Init_foo() method gives a
    strange error message like “tests/test.rb:3:in `require’: (null) -
    ./c/lib/i686-linux/foo.so (LoadError)”. The “(null)” looks like a %s being
    passed a null pointer.

  2. how do i get the selector of a message from the C method being called?
    i need to alias a method and then find back with which name it was called.
    this is equivalent to part of RCR #29
    (http://www.rubygarden.org/article.php?sid=89)
    but from C code instead.

  3. how do i create a Proc from a C function pointer? what should be the
    signature of that function? VALUE ()(int,VALUE,VALUE) ?

···

Mathieu Bouchard http://hostname.2y.net/~matju


(Nobuyoshi Nakada) #2

Hi,

  1. requiring a library that does not contain its Init_foo() method gives a
    strange error message like “tests/test.rb:3:in `require’: (null) -
    ./c/lib/i686-linux/foo.so (LoadError)”. The “(null)” looks like a %s being
    passed a null pointer.

Calling dlclose() before dln_error() clears error status. Try
following patches, the first for 1.6 and the second for 1.7.

  1. how do i get the selector of a message from the C method being called?
    i need to alias a method and then find back with which name it was called.
    this is equivalent to part of RCR #29
    (http://www.rubygarden.org/article.php?sid=89)
    but from C code instead.

You can get the ID with rb_frame_last_func().

  1. how do i create a Proc from a C function pointer? what should be the
    signature of that function? VALUE ()(int,VALUE,VALUE) ?

In 1.7,
VALUE rb_proc_new _((VALUE ()(ANYARGS/ VALUE yieldarg[, VALUE procarg] */), VALUE));

In 1.6, you can create an object and its singleton method, then
use Kernel#method and Method#to_proc.

Index: dln.c

···

At Sun, 16 Jun 2002 06:25:26 +0900, Mathieu Bouchard wrote:

RCS file: /cvs/ruby/src/ruby/dln.c,v
retrieving revision 1.15.2.12
diff -u -2 -p -r1.15.2.12 dln.c
— dln.c 2002/03/25 02:37:07 1.15.2.12
+++ dln.c 2002/06/16 04:06:24
@@ -11,6 +11,5 @@
**********************************************************************/

-#include “config.h”
-#include “defines.h”
+#include “ruby.h”
#include “dln.h”

@@ -1225,4 +1224,9 @@ dln_load(file)
const char *file;
{
+#if !defined(_AIX) && !defined(NeXT)

  • const char *error = 0;
    +#define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error))
    +#endif

#if defined _WIN32 && !defined CYGWIN
HINSTANCE handle;
@@ -1240,4 +1244,5 @@ dln_load(file)
/* Load file */
if ((handle = LoadLibrary(winfile)) == NULL) {

  • error = dln_strerror();
    goto failed;
    }
    @@ -1252,4 +1257,5 @@ dln_load(file)
    #ifdef USE_DLN_A_OUT
    if (load(file) == -1) {

  • error = dln_strerror();
    goto failed;
    }
    @@ -1276,8 +1282,10 @@ dln_load(file)
    /* Load file /
    if ((handle = (void
    )dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {

  •   error = dln_strerror();
      goto failed;
    

    }

    if ((init_fct = (void(*)())dlsym(handle, buf)) == NULL) {

  •   error = DLN_ERROR();
      dlclose(handle);
      goto failed;
    

@@ -1505,5 +1513,5 @@ dln_load(file)
#if !defined(_AIX) && !defined(NeXT)
failed:

  • rb_loaderror("%s - %s", dln_strerror(), file);
  • rb_loaderror("%s - %s", error, file);
    #endif
    }

    Index: dln.c
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/dln.c,v
    retrieving revision 1.34
    diff -u -2 -p -r1.34 dln.c
    — dln.c 2002/05/14 06:22:25 1.34
    +++ dln.c 2002/06/16 04:04:54
    @@ -11,6 +11,5 @@
    **********************************************************************/

-#include “config.h”
-#include “defines.h”
+#include “ruby.h”
#include “dln.h”

@@ -1242,4 +1241,9 @@ dln_load(file)
const char *file;
{
+#if !defined(_AIX) && !defined(NeXT)

  • const char *error = 0;
    +#define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error))
    +#endif

#if defined _WIN32 && !defined CYGWIN
HINSTANCE handle;
@@ -1257,4 +1261,5 @@ dln_load(file)
/* Load file */
if ((handle = LoadLibrary(winfile)) == NULL) {

  • error = dln_strerror();
    goto failed;
    }
    @@ -1271,4 +1276,5 @@ dln_load(file)
    #ifdef USE_DLN_A_OUT
    if (load(file) == -1) {
  • error = dln_strerror();
    goto failed;
    }
    @@ -1295,4 +1301,5 @@ dln_load(file)
    /* Load file /
    if ((handle = (void
    )dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
  •   error = dln_strerror();
      goto failed;
    
    }
    @@ -1301,4 +1308,5 @@ dln_load(file)
    free(buf);
    if (init_fct == NULL) {
  •   error = DLN_ERROR();
      dlclose(handle);
      goto failed;
    

@@ -1539,8 +1547,10 @@ dln_load(file)

if ((handle = (void*)dlopen(fname, 0)) == NULL) {
  •   error = dln_strerror();
      goto failed;
    

    }

    if ((init_fct = (void (*)())dlsym(handle, buf)) == NULL) {

  •   error = DLN_ERROR();
      dlclose(handle);
      goto failed;
    

@@ -1560,5 +1570,5 @@ dln_load(file)
#if !defined(_AIX) && !defined(NeXT)
failed:

  • rb_loaderror("%s - %s", dln_strerror(), file);
  • rb_loaderror("%s - %s", error, file);
    #endif
    return 0; /* dummy return */


Nobu Nakada


(Yukihiro Matsumoto) #3

Hi,

···

In message “Re: questions” on 02/06/16, nobu.nokada@softhome.net nobu.nokada@softhome.net writes:

At Sun, 16 Jun 2002 06:25:26 +0900, >Mathieu Bouchard wrote:

  1. requiring a library that does not contain its Init_foo() method gives a
    strange error message like “tests/test.rb:3:in `require’: (null) -
    ./c/lib/i686-linux/foo.so (LoadError)”. The “(null)” looks like a %s being
    passed a null pointer.

Calling dlclose() before dln_error() clears error status. Try
following patches, the first for 1.6 and the second for 1.7.

Commit them please.

						matz.