> 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


Reply via email to