> Here's my problem. DLL looked always magic to me, so I tried to work
> with them to see how it works. I wrote a DLL in Labwindow/CVI 6.0 and
> my first fonction had the following prototype
>
> extern int __cdecl MyDLL_Init (int In1,char *Out2);
>
....
> extern int __cdecl MyDLL_Init (int In1,char *Out2,char *Out3);
>
I'm not certain if this was a story or a request for an explanation, but
I'll give you my thoughts as to what you were seeing.
Both of these declarations are similar in that they pass one int by
value, and one or two string buffers by pointer. The string pointers,
or anything else by reference/pointer are the ones to watch for. The
problem here is that C just isn't very informative as to what this
really is. This could be a pointer to a single char, to an array of
char on the stack, or to an allocated block of memory. It could also be
NULL.
From the rest of your description, you intended to use it as an output.
The key here is that you, the caller, have to give the callee a buffer
to write into. The buffer belongs to the caller, the callee cannot
resize it, alloate it, or delete it. The callee just writes into the
buffer and in some way lets the caller know how many elements are there.
On return, the caller can read the data, resize, reuse, or destroy its
buffer. With more calls back and forth, or a more intertwined
relationship between the DLL and EXE, you can have the buffer be owned
by the DLL or even a third party, but the normal is that the caller owns
it. What you were probably seeing is that the CVI caller had a char[]
with enough space for the result. In LV, this is equivalent to putting
a string constant or initializing a string of the same size. If you
pass an empty string, that is equivalent to using char[1] in CVI, and
that will crash too.
As for the convention, typically called the calling convention, __cdecl
is one of the most widespread on other platforms, and I'm not sure where
std_call or standard came from. Anyway, I think there are four main
conventions that use the stack, and numerous others that use registers.
They main differences are who cleans up the stack (caller or callee),
and which order are the parameters on the stack. Some platforms have
one convention, others have another, and presumeably the common standard
is the one that is most resilient to bad calls or is the highest
permance one. Regardless, it is something that you have to get right.
About the only way to do that is read the header file or documentation
for the DLL. And on widows, they "wisely" chose to have most user
libraries use one standard and the OS libraries use the other, so you
have to pay attention to it. Actually, between the beta of NT 3.5 and
the release, they changed the convention and surprised everyone. We may
never know why.
Greg McKaskle