dl/loader ptr issue

B

Brian Caswell

--Apple-Mail-2-649242102
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed

I'm having fits with passing pointers to a function I've imported via
DL::Importable. I'm wrapping a simple opaque blob library (part of
libdnet). However, the function I'm wrapping doesn't seem to work as I
expect it to.

extern "int blob_read(void *blob, void *buf, int size)"

Basically, read the specified amount (size) from the blob, and put it
in buf. return status code. From what I've read, I should be able to
wrap this with something akin to:

def read (blob, len)
ptr = DL.malloc(len)
ret = Dnet.blob_read(blob, ptr.ref, len)
return ret.to_s
end

However, I get a EXC_BAD_ACCESS segv duing the to_s call. How should I
be getting access to buf?

My current test is attached. I have validated that the shared object
works as expected, when using dlopen/dlsym in C. (dnet.c works as an
example usage of the C api)

Brian


--Apple-Mail-2-649242102
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="dnet.rb"
Content-Disposition: attachment;
filename=dnet.rb

#!ruby
require 'dl/import'

module Dnet
extend DL::Importable
dlload "/sw/lib/libdnet.dylib"

extern "void *blob_new()"
extern "int blob_read(void *, void *, int)"
extern "int blob_write(void *, void *, int)"
extern "int blob_seek(void *, int, int)"

class Blob
@blob = nil

def initialize
@blob = Dnet.blob_new()
end

def write(str)
ret = Dnet.blob_write(@blob, str.to_ptr, str.length)
end

def rewind()
ret = Dnet.blob_seek(@blob, 0, 0)
end

def read(len)
ptr = DL.malloc(len)
ret = Dnet.blob_read(@blob, ptr.ref, len)
if ptr.size == 0
''
else
ptr.to_s
end
end
end
end

if $0 == __FILE__
blob = Dnet::Blob.new()
blob.write("hi")
blob.write("mom")
blob.rewind()
a = blob.read(2)
if a != "hi"
print "ACK! #{a} should be hi\n"
end
end

--Apple-Mail-2-649242102
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
x-unix-mode=0644;
name="dnet.c"
Content-Disposition: attachment;
filename=dnet.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>

main()
{
void *handle;
void *(*blob_new)(void);
int (*blob_write)(void *, void *, int);
int (*blob_read)(void *, void *, int);
int (*blob_seek)(void *, int, int);
int (*blob_free)(void *);
char *c;
char tmp[32];
void *blob;


handle = dlopen("/sw/lib/libdnet.dylib", 1);
if(dlerror()) { fprintf(stderr, "couldnt open libdnet.dylib\n"); abort(); }

blob_new = dlsym(handle, "blob_new");
if(dlerror()) { fprintf(stderr, "couldnt get blob_new symbol\n"); abort(); }

blob_write = dlsym(handle, "blob_write");
if(dlerror()) { fprintf(stderr, "couldnt get blob_write symbol\n"); abort(); }

blob_read = dlsym(handle, "blob_read");
if(dlerror()) { fprintf(stderr, "couldnt get blob_read symbol\n"); abort(); }

blob_seek = dlsym(handle, "blob_seek");
if(dlerror()) { fprintf(stderr, "couldnt get blob_seek symbol\n"); abort(); }

blob_free = dlsym(handle, "blob_free");
if(dlerror()) { fprintf(stderr, "couldnt get blob_free symbol\n"); abort(); }

blob = blob_new();
blob_write(blob, "foo", 3);
blob_write(blob, "bar", 3);
blob_seek(blob, 0, 0);
blob_read(blob, tmp, 3);
tmp[4] = 0;
printf("GOT %s\n", tmp);
blob_read(blob, tmp, 3);
printf("GOT %s\n", tmp);
tmp[4] = 0;
blob_seek(blob, 0, 0);
blob_read(blob, tmp, 6);
tmp[7] = 0;
printf("GOT %s\n", tmp);
blob_free(blob);
dlclose(handle);
}

--Apple-Mail-2-649242102--
 
T

Takaaki Tateishi

Brian said:
However, the function I'm wrapping doesn't seem to work as I
expect it to.

extern "int blob_read(void *blob, void *buf, int size)" ...
def read (blob, len)
ptr = DL.malloc(len)
ret = Dnet.blob_read(blob, ptr.ref, len)
return ret.to_s
end

How about using "ptr" instead of "ptr.ref"?
 
B

Brian Caswell

However, the function I'm wrapping doesn't seem to work as I
expect it to.

extern "int blob_read(void *blob, void *buf, int size)" ...
def read (blob, len)
ptr = DL.malloc(len)
ret = Dnet.blob_read(blob, ptr.ref, len)
return ret.to_s
end

How about using "ptr" instead of "ptr.ref"?[/QUOTE]

Thanks!

That worked, though the to_s doesn't, I needed to_str.

Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top