# C extensions question

**URL:** <https://www.ruby-forum.com/t/c-extensions-question/55709>\
**Category:** Ruby\
**Created:** [March 23, 2006, 4:04am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709 "2006-03-23T04:04:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 23, 2006, 4:04am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/1 "2006-03-23T04:04:45Z")

</div>

Hi all,

I haven’t done any “real” work in C in nearly 10 years and I’m still  
learning Ruby, so it’s quite possible that I’m just doing something  
dumb,  
but I’m stuck here. I’m trying to call Ingres database code from Ruby,  
so  
I’m writing some C extensions.

I have Ruby calling into C code. Very easy and very nice.

I have Ingres sample code (which is C) compiling and running fine.

However, when I try to invoke Ingres code from any of my C code and run  
it  
(from Ruby), I get a seg fault.

It feels like Ruby can’t see the Ingres libraries but the code samples  
don’t  
seem to having any problems. I suspect I’m missing something simple…

Do you need to do any special wrapping or declaring of code that isn’t  
touched from within your Ruby? I’ve been through the Pickaxe book and  
several online samples/tutorials and I don’t see that it’s needed… but  
then again, my code isn’t running. 🙂

Here’s my code as it is now… any hints or clues?

#include “ruby.h”

# include \<stdio.h\>

# include \<iiapi.h\>

static VALUE cIngres;

static VALUE ii\_exec(VALUE self) {  
printf(“\n\nExec was run from within the Ruby code \n\n”);  
IIAPI\_INITPARM initParm;  
printf(“one\n”);  
IIapi\_initialize( &initParm );  
printf(“two\n”);  
return Qnil;  
}

void Init\_Ingres() {  
cIngres = rb\_define\_class(“Ingres”, rb\_cObject);  
rb\_define\_method(cIngres, “exec”, ii\_exec, 0);  
}

Thanks!

Jared  
[http://jaredrichardson.net](http://jaredrichardson.net)

---

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 23, 2006, 4:18am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/2 "2006-03-23T04:18:12Z")

</div>

You’d better make the Makefile using extconf.rb, in which you can  
specify the library path and include path, as is told in the rubybook.

---

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 23, 2006, 5:34am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/3 "2006-03-23T05:34:37Z")

</div>

Good point. I should’ve mentioned that I am already doing that.

“Zeng Ke” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…

---

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 23, 2006, 7:35am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/4 "2006-03-23T07:35:56Z")

</div>

Hello Jared.

I’m not familiar with Ingres, but according to

> **[Actian X](https://www.actian.com/data-management/actian-x-hybrid-rdbms/)**
>
> Discover Actian X, combining the world-class Igres transactional database and vector analytics database, integration, monitoring, and more.

and this

[http://www.rubycentral.com/book/ext\_ruby.html](http://www.rubycentral.com/book/ext_ruby.html)

I’d write it this way:

-------------- \>8 --------------  
#include “ruby.h”  
#include \<iiapi.h\>

static VALUE rb\_cIngres;

static void  
ingres\_free(void \*p)  
{  
IIAPI\_RELENVPARM relEnvParm;  
IIAPI\_TERMPARM termParm;

```
relEnvParm.re_envHandle = p;
IIapi_releaseEnv(&relEnvParm);
/* test return status */
IIapi_terminate(&termParm);
/* test return status */

```

}

static VALUE  
ingres\_alloc(VALUE klass)  
{  
IIAPI\_INITPARM initParm;  
/\*  
\* initialize initParm structure here  
\* before passing it along to IIapi\_initialize  
_/  
IIapi\_initialize(&initParm);  
if (initParm.in\_status != IIAPI\_ST\_SUCCESS) {  
initParm.in\_envHandle = NULL;  
/_ do something else probably \*/  
}  
return Data\_Wrap\_Struct(klass, 0, ingres\_free, initParm.in\_envHandle);  
}

static VALUE  
ingres\_init(VALUE self)  
{  
/\* Initialization stuff \*/  
return self;  
}

void Init\_ingres(void) {  
rb\_cIngres = rb\_define\_class(“Ingres”, rb\_cObject);  
rb\_define\_method(rb\_cIngres, “initialize”, ingres\_init, 0);  
}  
-------------- 8\< --------------

But I can’t test it.

2006/3/22, Jared R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> IIAPI\_INITPARM initParm;
> 
> Thanks!
> 
> Jared  
> [http://jaredrichardson.net](http://jaredrichardson.net)

–  
Gerardo S.  
“Between individuals, as between nations, respect for the rights of  
others is peace” - Don Benito Juárez

> **[Santana's Tech Notes](http://santanatechnotes.blogspot.com/)**
>
> Small notes about technical related stuff I do, mainly OpenBSD and Ruby

---

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 23, 2006, 1:49pm UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/5 "2006-03-23T13:49:02Z")

</div>

My original code was written just like that but I cut it down for the  
newsgroup posting. 🙂

Thanks!

“Gerardo S. Gómez Garrido” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in  
message  
news:removed\_email\_address@domain.invalid…  
Hello Jared.

I’m not familiar with Ingres, but according to

> **[Actian X](https://www.actian.com/data-management/actian-x-hybrid-rdbms/)**
>
> Discover Actian X, combining the world-class Igres transactional database and vector analytics database, integration, monitoring, and more.

and this

[http://www.rubycentral.com/book/ext\_ruby.html](http://www.rubycentral.com/book/ext_ruby.html)

I’d write it this way:

-------------- \>8 --------------  
#include “ruby.h”  
#include \<iiapi.h\>

static VALUE rb\_cIngres;

static void  
ingres\_free(void \*p)  
{  
IIAPI\_RELENVPARM relEnvParm;  
IIAPI\_TERMPARM termParm;

relEnvParm.re\_envHandle = p;  
IIapi\_releaseEnv(&relEnvParm);  
/\* test return status _/  
IIapi\_terminate(&termParm);  
/_ test return status \*/  
}

static VALUE  
ingres\_alloc(VALUE klass)  
{  
IIAPI\_INITPARM initParm;  
/\*

- initialize initParm structure here
- before passing it along to IIapi\_initialize  
_/  
IIapi\_initialize(&initParm);  
if (initParm.in\_status != IIAPI\_ST\_SUCCESS) {  
initParm.in\_envHandle = NULL;  
/_ do something else probably \*/  
}  
return Data\_Wrap\_Struct(klass, 0, ingres\_free, initParm.in\_envHandle);  
}

static VALUE  
ingres\_init(VALUE self)  
{  
/\* Initialization stuff \*/  
return self;  
}

void Init\_ingres(void) {  
rb\_cIngres = rb\_define\_class(“Ingres”, rb\_cObject);  
rb\_define\_method(rb\_cIngres, “initialize”, ingres\_init, 0);  
}  
-------------- 8\< --------------

But I can’t test it.

2006/3/22, Jared R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> then again, my code isn’t running. 🙂  
> printf(“\n\nExec was run from within the Ruby code \n\n”);  
> }
> 
> Thanks!
> 
> Jared  
> [http://jaredrichardson.net](http://jaredrichardson.net)

–  
Gerardo S.  
“Between individuals, as between nations, respect for the rights of  
others is peace” - Don Benito Juárez

> **[Santana's Tech Notes](http://santanatechnotes.blogspot.com/)**
>
> Small notes about technical related stuff I do, mainly OpenBSD and Ruby

---

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 25, 2006, 2:59am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/6 "2006-03-25T02:59:00Z")

</div>

Also, I forgot to add, in order for this to work, invoke with these  
options:

ruby -r mkmf  
xtconf.rb --with-ingres-include=“/opt/Ingres/IngresII/ingres/files/”  
–with-ingres-lib=“/opt/Ingres/IngresII/ingres/lib/”

“Jared R.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:Yi1Vf.44009$removed\_email\_address@domain.invalid…

---

<div class="post-metadata">

**Author:** ![Jared\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a4c791/32.png) [@Jared\_R](https://www.ruby-forum.com/u/Jared_R)\
**Post date:** [March 25, 2006, 2:49am UTC](https://www.ruby-forum.com/t/c-extensions-question/55709/7 "2006-03-25T02:49:03Z")

</div>

I finally got this thing working so I thought I’d share the answer, even  
though it was a simple problem (once I found it.) 🙂

I was already generating my Makefile with extconf.rb but I hadn’t gotten  
it  
to answer “yes” to any of the have\_library or find\_libary calls. I did  
have  
it working for have\_header. I should’ve focused on that have\_library  
that  
answered “no”, but I thought that since the original C samples could run  
with the libraries in the LD\_LIBRARY\_PATH environment variable that the  
Ruby  
code would be okay. It wasn’t. 🙂

It turns out that I wasn’t using the right library name. The include was  
called “iiapi.h” and the compiled library was named libiiapi.a (static)  
and  
libiiapi.1.so (dynamic). However the name of the library seems to be  
“ingres”. I’m pretty sure I tried using “ingres” early in the debugging  
cycle, but it appears that either I didn’t or that I had the environment  
messed up at the time.

I haven’t done anything “real” with the resulting code yet, but I can  
call  
into the ingres library without a segmentation fault, so I’m going to  
call  
it good and go take a break. 🙂

I’m pasting in my extconf.rb for future reference.

* * *

require ‘mkmf’

dir\_config(“ingres”)  
have\_header(“iiapi.h”)  
have\_library(“ingres”)

$CFLAGS = " -g -Dint\_lnx -O "  
incdir = ENV[“II\_SYSTEM”] + “/ingres/files”  
$CFLAGS += “-I#{incdir}”  
libdir = ENV[“II\_SYSTEM”] + “/ingres/lib”  
$LDFLAGS += “-L#{libdir}”  
$LDFLAGS += " -lingres -lpthread -lm -lc -lcrypt -ldl -lgcc\_s"

## create\_makefile(“Ingres”)

Thanks for the suggestions and help.

Jared  
[http://jaredrichardson.net](http://jaredrichardson.net)

* * *

## — Original Message ----

Hi all,

I haven’t done any “real” work in C in nearly 10 years and I’m still  
learning Ruby, so it’s quite possible that I’m just doing something  
dumb,  
but I’m stuck here. I’m trying to call Ingres database code from Ruby,  
so  
I’m writing some C extensions.

I have Ruby calling into C code. Very easy and very nice.

I have Ingres sample code (which is C) compiling and running fine.

However, when I try to invoke Ingres code from any of my C code and run  
it  
(from Ruby), I get a seg fault.

It feels like Ruby can’t see the Ingres libraries but the code samples  
don’t  
seem to having any problems. I suspect I’m missing something simple…

Do you need to do any special wrapping or declaring of code that isn’t  
touched from within your Ruby? I’ve been through the Pickaxe book and  
several online samples/tutorials and I don’t see that it’s needed… but  
then again, my code isn’t running. 🙂

Here’s my code as it is now… any hints or clues?

#include “ruby.h”

# include \<stdio.h\>

# include \<iiapi.h\>

static VALUE cIngres;

static VALUE ii\_exec(VALUE self) {  
printf(“\n\nExec was run from within the Ruby code \n\n”);  
IIAPI\_INITPARM initParm;  
printf(“one\n”);  
IIapi\_initialize( &initParm );  
printf(“two\n”);  
return Qnil;  
}

void Init\_Ingres() {  
cIngres = rb\_define\_class(“Ingres”, rb\_cObject);  
rb\_define\_method(cIngres, “exec”, ii\_exec, 0);  
}

Thanks!

Jared  
[http://jaredrichardson.net](http://jaredrichardson.net)
