[Prev][Next][Index][Thread]

Working with C strings in HD 1.2



In Harlequin Dylan 1.2:

I'm using a Windows API function that returns a pointer to a shared
memory buffer typed as <LPVOID>. The pointer returned is the result of
a MapViewOfFile call:

  let pointer = MapViewOfFile(handle, $FILE-MAP-ALL-ACCESS, 0, 0, 0);

I need to place a zero terminated string into this buffer, call
another API function and then retrieve another zero terminated string
containing the results. I'm a bit unsure as the best way of getting
the information into and out of the buffer.

I need to place the request information at position 100 in the
buffer. So far I'm doing something like:

    let buffer  = c-type-cast(<c-unsigned-char*>, pointer);
    let request-string = "Some request data";
    let index = 100;
    for(char in request-string)
      buffer[index] := as(<integer>, char);
      index := index + 1;
    end for;
    buffer[index] := 0;

I have to convert each character to an <integer> for it to work
otherwise I get a type error on the assign. Is there some function or
method I can call that does this without the need to call
as(<integer>) on each character of the request string?

The result I need to get out of the buffer is also a zero terminated
string. I don't know the length of it, I only know the starting
location. How best to get the information out of the buffer and into a
<byte-string> or <c-string>? At the moment I'm doing the rather slow:

    let index = 100;
    let count = 0;
    while(buffer[index] ~= 0)
      count := count + 1;
      index := index + 1;
    end while;
    let result = make(<byte-string>, size: count);
    for(index2 from 0 below count)
      result[index2] := $char-map[buffer[index2 + 100]];
    end for;

Where $char-map is:

  define constant $char-map :: <simple-object-vector> = 
    make(<simple-object-vector>, size: 256);

  begin
    for(i :: <integer> from 0 below 256)
      $char-map[i] := as(<character>, i);
    end for;
  end;

I found if I did the as(<character>, ...) in the loop then things
slowed down a lot. The vector lookup was faster. The result can be
values of over 1,000,000 characters and a number of these calls can be
made. Any advice on speeding up the transfer of this information? Is
there a way of creating a <c-string> that points to an existing memory
location so I can create one pointing directly into the buffer?

It's been a while since I've done any c-ffi stuff and my mind has
drawn a blank.

Thanks for any assistance,
Chris.