Re: #<Pointer to type FLI::WCHAR-T = #x003F6E70> cannot be converted to
foreign type (:POINTER :WCHAR-T)
Sorry to drag this old post up again, but I have encountered some similar
problems.
I also opted for the "just use :POINTER" approach - which seems to work..
I am using one of those Windows API calls where the first call tells you
how big the buffer needs to be to hold the answer.
Then you call it again with the right size buffer to get the answer you
really wanted in the first place.
The code is below.
As in the original post, it is modeled on the third example from FLI Manual
4.2.2 Modifying a string in a C function.
I had to use :wchar-t to get it to work with Unicode pathnames on XP.
This does not tie up with Dave's comment that "I have never seen a use for
:wchar-t "
Is this a valid use of :wchar-t ? or is there a better way to do this ?
Any insights appreciated.
Thanks
paulm
(defmacro os-external-format ()
'(if (string= (software-type) "Windows NT")
:unicode
win32:*multibyte-code-page-ef*))
(defmacro os-character-type ()
'(if (string= (software-type) "Windows NT")
:wchar-t
:char))
#|
__declspec(dllimport) unsigned long __stdcall GetShortPathNameA(
constant char * lpszLongPath,
char * lpszShortPath,
unsigned long cchBuffer
);
__declspec(dllimport) unsigned long __stdcall GetShortPathNameW(
constant wchar_t * lpszLongPath,
wchar_t * lpszShortPath,
unsigned long cchBuffer
);
|#
(fli:define-foreign-function (get-short-path-name-win32 "GetShortPathName"
:dbcs)
((lpszLongPath (:pointer))
(lpszShortPath (:pointer))
(cchBuffer (:unsigned :int)))
:result-type
(:unsigned :int)
:language :c
:calling-convention :stdcall)
(defun get-short-path-name (long-path-name)
(fli:with-foreign-string (lp-long-path-name element-count byte-count
:external-format
(os-external-format))
long-path-name
(declare (ignorable element-count byte-count))
(fli:with-dynamic-foreign-objects ()
(let* ((lp-zero-buffer
(fli:allocate-dynamic-foreign-object :type
(os-character-type) :nelems 0))
(short-path-name-size
(get-short-path-name-win32 lp-long-path-name lp-zero-buffer 0))
(lp-short-path-name-buffer
(fli:allocate-dynamic-foreign-object :type
(os-character-type) :nelems short-path-name-size)))
(get-short-path-name-win32 lp-long-path-name
lp-short-path-name-buffer short-path-name-size)
(fli:convert-from-foreign-string lp-short-path-name-buffer
:external-format
(os-external-format))))))
At 15:44 02/09/2004, Edi Weitz wrote:
>On Thu, 2 Sep 2004 15:13:11 +0100, davef@xanalys.com wrote:
>
> > Instead, use the foreign type :EF-WC-STRING with :REFERENCE-PASS to
> > pass Unicode strings via the FLI.
>
>According to the FLI docs (4.2.2) this will only work if I "can bound
>the size of the result string at compile-time." This is not the case
>for my application.
>
>It looks to me as if I have to use something like the third example
>from 4.2.2 and you use :POINTER there, too, so maybe I should just do
>it.
>
> > > but I don't understand what's wrong with the first definition.
> What's the
> > > difference between a
> > >
> > > #<Pointer to type FLI::WCHAR-T = #x003F6E70>
> > >
> > > and a (:POINTER :WCHAR-T)?
> >
> > The foreign type :WCHAR-T isa convertor between a Lisp character and
> > a C wchar_t, but I've never seen a use for it and the FLI does not
> > know how to convert it to the internal FLI::WCHAR-T type used for
> > strings.
> >
> > > I thought that WITH-FOREIGN-STRING with the appropriate external
> > > format is supposed to create a (:POINTER :WCHAR-T)...
> >
> > Why did you think that?
>
>The receiving C++ function expects a pointer to wchar_t and LispWorks
>creates something internally that it calls a "Pointer to
>FLI::WCHAR-T." I don't think it is too far-fetched from me to see a
>similarity between these two things and (:POINTER :WCHAR-T).
>
>Anyway, I'll just use :POINTER.
>
>Thanks,
>Edi.