Rules for DLL Function Signatures
Hi,
Are there any specific rules as regards parameters that make up a DLL function signature which is exposed to the outside world ?
In addition, Is it an accepted practice to have DLL function signatures which
1.Take class objects as parameters (object parameters, pointer to object or reference to object)
2. Return class objects as parameters (object parameter, pointer to object parameter, or reference object)
I suppose it is acceptable to return an object pointer from a DLL, because that is one of the ways in which plug-ins are implemented (where the return type is an Interface pointer)
Please do let me know.
The DLL is expected to be consumed by C or C++ clients.
Re: Rules for DLL Function Signatures
1. Yes.
2. Yes.
3. For any object allocated in Dll, supply Release function which should delete it. Client should not try to release objects allocated in another Dll.
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Alex F
1. Yes.
2. Yes.
3. For any object allocated in Dll, supply Release function which should delete it. Client should not try to release objects allocated in another Dll.
Yes, this is the correct guideline. There are some exceptions to rule 3), and that is if The DLL uses the Windows API to allocate the memory (i.e. GlobalAlloc and those funtions).
For example, various third-party DLL's that deal with imaging will allocate the memory using GlobalAlloc, HeapAlloc, etc. and it's the responsibiltiy of the app to release the image memory. Of course, this needs to be documented to the user of the DLL.
Regards,
Paul McKenzie
Re: Rules for DLL Function Signatures
Quote:
1.Take class objects as parameters (object parameters, pointer to object or reference to object)
2. Return class objects as parameters (object parameter, pointer to object parameter, or reference object)
I would say no to both. What if the class definition changes and function is still assuming the old version' class has been passed, or vice versa. The same goes for returning a class object - doesn't matter if you return the object or the pointer to object.
Would you ever try to return std::vector from a DLL function? Or would you expect a function taking map<string,list<int>::iterator> & ? These classes would definitely change! The client might be using other version of STL, and your DLL might be working in other version of STL. STL doesn't have DLL, no runtime library, thus size/definition would definitely differ!
The only case, where I can expect taking/returning the class, when the same DLL is exporting the classes. Even in that case, I may check at runtime - using ASSERT to check it in debug, and performing sizeof checks in release. Though, for performance reasons, I may omit runtime check at release version.
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Ajay Vijay
IWould you ever try to return std::vector from a DLL function? Or would you expect a function taking map<string,list<int>::iterator> & ?
Yes, STL objects should never be passed between Dll and its client. This is well-known problem. Interesting, what is general rule for all templates, not only STL.
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Alex F
Yes, STL objects should never be passed between Dll and its client. This is well-known problem. Interesting, what is general rule for all templates, not only STL.
I would not take the trouble of passing CDataExchange or CWordArray either. :cool:
Re: Rules for DLL Function Signatures
Quote:
I suppose it is acceptable to return an object pointer from a DLL, because that is one of the ways in which plug-ins are implemented (where the return type is an Interface pointer)
- Pointer to object is not the same thing as interface pointer
- Interface pointer is a standard way for dealing with/interchanging objects in plugin technology
- Interface declaration must follow __stdcall convention to guarantee real cross-compiler compatibility
Re: Rules for DLL Function Signatures
Quote:
Interface declaration must follow __stdcall convention to guarantee real cross-compiler compatibility
Did you mean the object-oriented interface term, or the interface you are giving via your exported functions? Former is not possible since calling conventions apply to functions only. Latter doesn't fit the discussion.
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by Ajay Vijay
Former is not possible since calling conventions apply to functions only.
Actually, this is what I meant (not sure what you did):
Code:
typedef struct {
virtual int __stdcall foo0() = 0;
virtual int __stdcall foo1(int a) = 0;
virtual int __stdcall foo2(int a, int b) = 0;
} MyFooInterface, *PMyFooInterface;
Re: Rules for DLL Function Signatures
The discussion is about arguments and return types from a function.
And typedefining a structure with virtual function?? :eek:
Re: Rules for DLL Function Signatures
The only time I would expose classes from a dll is if I only used the dll within exe projects I controlled. That way, I could always rebuild both the exe and the dll.
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Ajay Vijay
The discussion is about arguments and return types from a function.
Yep, exactly. Arguments and return types, as well as objects and interfaces, dlls and plug-ins. ;)
Quote:
And typedefining a structure with virtual function?? :eek:
Man, it looks like you never delved into COM and plug-in technologies. Lucky guy. :)
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Igor Vartanov
Yep, exactly. Arguments and return types, as well as objects and interfaces, dlls and plug-ins.
The OP asked if it is okay to pass or return the class objects. Interfaces are different thing. Yes you can pass interfaces, with less issues than classes. The definition of interface, and importance of it are off beat, as per this thread.
Quote:
Man, it looks like you never delved into COM and plug-in technologies. Lucky guy. :)
Hmm. You did not get me. A typedef struct {...}theStruct; definition reminds me of C, and code compatibility with C. Now, when you include a pure virtual function in it, it become obscure.
COM Interaface? Well, that also uses IDL/ODL files, which are composed of classes/coclasses and not C-style struct typedefs.
Quote:
Interface declaration must follow __stdcall convention to guarantee real cross-compiler compatibility
This seriously has nothing to do with DLL exported function signatures, taking class objects.
Re: Rules for DLL Function Signatures
@Igor,
I guess you are more concerned about this following statement.
Quote:
I suppose it is acceptable to return an object pointer from a DLL, because that is one of the ways in which plug-ins are implemented (where the return type is an Interface pointer)
But, in my way of interpreting it, he is just giving an example on how Plug-ins are implemented. With that knowledge, he is quite sure that object/class-pointer may be returned from an exported DLL function. But again, I believe, he is not concerned about interfaces as such, and __stdcall convention in interfaces.
Re: Rules for DLL Function Signatures
Ajay, I really appreciate your input. But would you just slow down with guessing? and let the thread originator utter a couple of words about his real point of interest? Thank you. :)
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Ajay Vijay
STL doesn't have DLL, no runtime library, thus size/definition would definitely differ!
Ajay, that is indeed an interesting point about not returning STL objects. What did you exactly mean when you said STL doesn't have DLL, no runtime library etc ?
Is it safe to return std::string from DLL functions.
Re: Rules for DLL Function Signatures
[Regarding what I meant with regard to interfaces]
Imagine that I had an interface class as follows :
Code:
class IDisplay
{
virtual void Display(char * _p) = 0;
}
I could implement it by extending to implement the following classes :
Code:
class ConsoleDisplay : public IDisplay
{
virtual void Display(char *_p)
{
}
}
class FileDisplay : public IDisplay
{
virtual void Display(char *_p)
{
}
}
Both the above class implementations would be in the DLL.
Now, there could be a function being exposed out of the DLL as follows :
__declspec(dllexport) IDisplay * GetDisplayInstance()
The implementation of GetDisplayInstance() would be to instantiate either FileDisplay or ConsoleDisplay based on some condition.
I had asked the earlier question keeping this scenario in mind with regard to returning object pointers in the guise of interface pointers.
I would like to understand if Igor would make any changes to the way the IDisplay interface is declared (like typing in the _stdcall convention in the signature) and why ?
Ajay, everyone, your comments are also requested - it is good learning indeed.
Somehow I was under the impression that it was best to deal with Basic Data Types when using DLL function signatures, but it seems it is perfectly OK to deal with classes as return types or parameters (except for the cases that Ajay and the others have pointed out)
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
humble_learner
Is it safe to return std::string from DLL functions.
It isn't practical, as there are too many pitfalls involved.
What if the DLL was created with one version of the compiler, and the app is using another version of the compiler? What if the std::string internals for each version is different?
In addition, let's assume that the DLL and app are built with the same compiler and version. What if the DLL is compiled with one set of options and the app is compiled with a different set of options, making std::string slightly different between the two versions?
OK, let's assume you are compiling with the same options. What if the DLL is using one heap to allocate memory, and the app uses a separate heap for memory allocations. What if the std::string allocates memory in the DLL to do it's internal housekeeping, and then the app takes this string and the std::string on the app side attempts to free or reallocate memory? That isn't going to work, since the heaps are different, and one heap knows nothing about what the other heap is doing or has done. That's a crash waiting to happen.
So all of these things need to be consistent -- same compiler, same version of the compiler, same compiler options, same heap. All of these have to be in sync for any passing of std::string from DLL to app to work successfully.
Regards,
Paul McKenzie
Re: Rules for DLL Function Signatures
Back to original problem :)
__declspec(dllexport) IDisplay * GetDisplayInstance();
__declspec(dllexport) ReleaseDisplayInstance(IDisplay*);
Looks OK for me.
Is it safe to return std::string from DLL functions?
Never use STL types in Dll interface.
STL doesn't have DLL, no runtime library etc.
Like all template libraries, STL is completely inline. This is not Dll, just a lot of h-files.
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Paul McKenzie
It isn't practical, as there are too many pitfalls involved.
So all of these things need to be consistent -- same compiler, same version of the compiler, same compiler options, same heap. All of these have to be in sync for any passing of std::string from DLL to app to work successfully.
Regards,
Paul McKenzie
Thanks Paul for that very detailed explanation. So in short, in case one does have to return strings to the calling application, it is best to use char * right ?
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
Alex F
Back to original problem :)
Like all template libraries, STL is completely inline. This is not Dll, just a lot of h-files.
Thanks Alex for clarifying regarding how STL is. Somehow I was tending to think it is a DLL.
Would you actually consider std::string to be part of the STL - because there is nothing "template" about that right ? Shouldn't the implementation of std::string be a DLL or something ?
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
humble_learner
Thanks Alex for clarifying regarding how STL is. Somehow I was tending to think it is a DLL.
Would you actually consider std::string to be part of the STL - because there is nothing "template" about that right ?
Wrong. A std::string is just a typedef for a template based on the char data type.
Code:
typedef basic_string<char, char_traits<char> > string;
or something similar to that.
However, just because something is a template doesn't mean it has anything to do with STL. There are standard classes that are based on templates that are not part of STL. The stream classes are a good example of this.
Regards,
Paul McKenzie
Re: Rules for DLL Function Signatures
Quote:
Originally Posted by
humble_learner
So in short, in case one does have to return strings to the calling application, it is best to use char * right ?
You may return const char* for constant strings. For dynamic strings, make function prototype like:
size_t GetString(char* buffer, size_t bufferSize);
Function fills buffer which has at least bufferSize length (caller's responsibility), and returns number of characters actually filled.