# C extension question

**URL:** <https://www.ruby-forum.com/t/c-extension-question/69114>\
**Category:** Ruby\
**Created:** [September 18, 2006, 7:58pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114 "2006-09-18T19:58:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 7:58pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/1 "2006-09-18T19:58:42Z")

</div>

So I’m making some headway on a kerberos 5 extension for ruby. It’s  
limited at the moment to authorizing a user, changing a user password,  
creating principals, and deleting principals, but it’s working. Now  
I’m trying to refactor it a bit and need some assistance. I’ve never  
really coded in C before so bear with me…

In kerberos when doing an administration function I first need to  
initialize the system with the credentials of an administrative user  
like so, with handle being a void pointer initialized to NULL. The  
following kerberos function will fill handle with a handle for the  
connection which I can use in subsequent calls to other kadm5  
functions.

kadm5\_init\_with\_password(auser, apass, KADM5\_ADMIN\_SERVICE, NULL,  
KADM5\_STRUCT\_VERSION, KADM5\_API\_VERSION\_2, &handle);

Now what I’d like is to return that handle to ruby and be able to pass  
it back into my C extension when it’s needed, such as when needing to  
call the following kerberos function.

kadm5\_create\_principal(handle, &princ, mask, pass);

So how would I do this? If I understand void pointers correctly,  
handle could be any type after the call to kadm5\_init\_with\_password,  
so it seems I would want to check it’s type after it’s set, then find  
the right type/structure to convert it to or wrap it in before passing  
it back to ruby? Not that I know how to do that:)

Chris

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 8:38pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/2 "2006-09-18T20:38:47Z")

</div>

On 9/18/06, snacktime [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> it back to ruby? Not that I know how to do that:)
> 
> Chris

Void\* is almost always the same size as the native integer. (There is  
legitimate controversy over this point but you can depend on it for all  
ends  
and intents.) So when the kerb function returns having filled in your  
void\*,  
you can cast it to a native unsigned and then pass it back to Ruby as a  
VALUE returned from INT2NUM. (I wouldn’t use INT2FIX because you’ll need  
all  
of the native resolution.) To pass the value back into C, convert it to  
an  
int with NUM2INT and cast to a void\*. I would expect (but can’t say for  
sure) that this will work on 64-bit platforms (where void\* is eight  
bytes  
wide) as long as the Ruby conversion functions are defined on the native  
integer.

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 9:14pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/3 "2006-09-18T21:14:51Z")

</div>

> Better to wrap it as a data type in Ruby, which gives you a ruby VALUE  
> which references the native data. There’s a simple macro to grab the  
> original pointer given the VALUE.
> 
> DEC Alpha doesn’t necessarily have sizeof(int) == sizeof(void \*), so  
> please don’t assume so. I hate fixing code that does that. 😉
> 
> Aria (A kerberos user, too!)

Well I’ll do the grunt work and then when I release it I’ll accept  
patches from those with more C experience than I have. I actually  
can’t remember if I ever wrote a C program before, but I’ve been  
meaning to learn it so I figured this was as good a project as any  
since we have some use for kerberos bindings.

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 8:44pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/4 "2006-09-18T20:44:48Z")

</div>

On Tue, 2006-09-19 at 03:39 +0900, Francis C. wrote:

> > KADM5\_STRUCT\_VERSION, KADM5\_API\_VERSION\_2, &handle);  
> > the right type/structure to convert it to or wrap it in before passing  
> > it back to ruby? Not that I know how to do that:)

> Void\* is almost always the same size as the native integer. (There is  
> legitimate controversy over this point but you can depend on it for all ends  
> and intents.)

Better to wrap it as a data type in Ruby, which gives you a ruby VALUE  
which references the native data. There’s a simple macro to grab the  
original pointer given the VALUE.

DEC Alpha doesn’t necessarily have sizeof(int) == sizeof(void \*), so  
please don’t assume so. I hate fixing code that does that. 😉

Aria (A kerberos user, too!)

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 9:32pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/5 "2006-09-18T21:32:53Z")

</div>

On 9/18/06, Aredridel [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> DEC Alpha doesn’t necessarily have sizeof(int) == sizeof(void \*), so  
> please don’t assume so. I hate fixing code that does that. 😉

It’s been over five years since the last time I programmed an Alpha in  
C. Do  
you have Ruby running on yours? Are you running DEC/Unix on them? As I  
recall, pointers are always a flat 64-bits on Alpha but ints come in  
several  
flavors, so you would have to cast the void\* carefully to keep from  
narrowing it, but it would fit just fine in a Ruby Bignum.

Are you suggesting to use StringValue and StringValuePtr, and treat the  
void\* as a char\*?

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 9:49pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/6 "2006-09-18T21:49:00Z")

</div>

One more unrelated question. I’m trying to think of the best way to  
do the interface, particularly how to access error messages and what  
to return to the caller. For most functions the caller just needs to  
know if the function returned true, or if there was an error a way to  
get the error message. So, I could for example return 0 on success or  
the error message number on failure. Or I could return true/false,  
store any error message number in a C global variable, and then have a  
function which returns the text error message if the original function  
returned false.

The latter seems more intuitive. For example

krb = Krb5.new  
if krb.authenticate\_with\_password(user,pass)

# authenticated

else  
p krb.errstr  
end

As opposed to:

res = krb.authenticate(user,pass)  
if res == 0

# authenticated

else  
p krb.errstr(res)  
end

And in the case where a method returns a handle that will be used  
later, I’m thinking return the handle on success, and on failure  
return nil and make the error available via krb.errstr?

Chris

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 9:59pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/7 "2006-09-18T21:59:00Z")

</div>

On 9/18/06, snacktime [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The latter seems more intuitive. For example  
> And in the case where a method returns a handle that will be used  
> later, I’m thinking return the handle on success, and on failure  
> return nil and make the error available via krb.errstr?

I’m guessing because I haven’t seen your code but I’d say it’s much  
more Ruby-esque to return a boolean value rather than a zero (which  
Ruby evaluates true). Hiding the error string behind an accessor makes  
sense if it will be accessed infrequently. You do have to remember to  
clear it on _every_ call into your extension.

Why make your user touch the handle at all? Can you hide it inside  
your Krb5 objects with instance\_eval, and just supply it yourself when  
you need to pass it to the kerb library?

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [September 18, 2006, 10:47pm UTC](https://www.ruby-forum.com/t/c-extension-question/69114/8 "2006-09-18T22:47:07Z")

</div>

> Why make your user touch the handle at all? Can you hide it inside  
> your Krb5 objects with instance\_eval, and just supply it yourself when  
> you need to pass it to the kerb library?

I’m not picturing this for some reason, can you elaborate?

Chris
