Monday, September 19, 2011

Re: libcall problem under windows

On 19/09/11 20:17, niva wrote:
> Hi,
>
> After linking this dll ...
>
> .h
> extern "C" __declspec(dllexport) char * decrease(int * a);
>
> .cpp
> extern "C" __declspec(dllexport)
> char * decrease(int * a)
> {
> *a = - *a;
> return NULL;
> }
>
> ...I call it from gvim with this command
> echo libcall("dlltest.dll", "decrease", "5")
>
> but I get the E364 error
>

From :help libcall()

[...] The function must take exactly one parameter, either a character
pointer or a long integer, and must return a character pointer or NULL.
[...]

So why are you declaring the function with a pointer to an integer, then
passing it a pointer to a character string? The function, if it did no
type-checking, would get 0x35 0x00 ("5" followed by a null byte on 16
bits), interpret it as the low word of a 32-bit integer, and change it
and the following word to their arithmetic opposite, altering the string
constant to something which is not a proper null-terminated string, and
altering whatever is found in the next two bytes of memory, with
unspecified results. If you want to get one less than the argument (as
suggested by the name "decrease") I propose the following (untested)
which uses libcallnr() rather than libcall() since we want to return a
numeric value rather than a string:

.h
extern "C" __declspec(dllexport) int decrease(long a);

.cpp
extern "C" __declspec(dllexport)
int decrease(long a)
{
return (a-1);
}

:echo libcallnr('dlltest', 'decrease', 5)

(with no quotes around the 5) which should return 4 if I didn't goof,
though I'm not sure why libcallnr() should take a long and return an
int. Maybe I misunderstood.

Or if you want to change the sign in-place of an integer variable (as
implied by the code you sent), well, you can't, because (the way I
understand the help) libcall() doesn't take a pointer to an integer but
either a pointer to a character string, or a long integer passed by
value. But of course you could do that without libcall() by using simply

:let foo = -foo

or for the decrement case (the example I gave above)

:let foo -= 1


Best regards,
Tony.
--
If I kiss you, that is a psychological interaction.

On the other hand, if I hit you over the head with a brick, that is
also a psychological interaction.

The difference is that one is friendly and the other is not so
friendly.

The crucial point is if you can tell which is which.
-- Dolph Sharp, "I'm O.K., You're Not So Hot"

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments:

Post a Comment