Solved

Exporting class from a dll with a .def file

Posted on 1998-06-29
12
1,206 Views
Last Modified: 2012-05-04
How to export a C++ non-MFC class from a dll(not a MFC extension dll) with a .def file? Almost all books just tell the readers to use _declspec(). This is really simple. But the VC documentation said that you will have to recompile all .exe files that use the dll if more functions is added to the class! Therefore, I wanted to use a .def file. However, I can find only documentations of exporting functions with a .def file. How to export an entire class? And can I import the class from this dll with _declspec()?

Also, is there any web sites or books that talk about .def files?(I mean talk about some more difficult topics like the question I'm asking)
0
Comment
Question by:sccheung
  • 4
  • 3
  • 3
  • +2
12 Comments
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Using a DEF file will not relieve the requirement to rebuild clients of the DLLs if the class receives more virtual functions, has the existing virtual functions reordered, or gains more member data.

The only way to achieve the late-binding that you're asking for is to use GetProcAddress() on the client side, which is tedious and error-prone at best.

B ekiM

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
You can use a .def file just like normal, but the problem is that if the procedures are not declared extern "C", you need to specify the procedures' decorated names.  That is rather ugly.  You are best of just using _declspec(dllexport).  I suspect that is largely the reason it was developed.
0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Of course, you can't declare the member of a class extern "C" because they must be declared as __thiscall, unless they're static members.

B ekiM



0
 
LVL 2

Expert Comment

by:rayb
Comment Utility
Have you considered using COM?  This is one of the fundamental operations/purposes of COM.
0
 
LVL 3

Expert Comment

by:danny_pav
Comment Utility
An alternate version goes like this:
declare wrapper functions for each class member

class MyClass {
  public:
    MyClass();
    ~MyClass();

private:
  ...

public:
  void DoIt();
};

you would then make an .h file like:

#ifdef __cpluplus
extern"C" {
#endif

typedef void * HMYCLASS;

HMYCLASS MyClass_New();
void MyClass_Delete(HMYCLASS h);
void MyClass_DoIt(HMYCLASS h);

#ifdef __cpluplus
}
#endif

I left out the necessary declspec stuff, but you get the idea.
Then each of those wrappers has to call the approprate class member.

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
What danny didn't mention was that these interface functions could then be listed in the .def file. as they are extern "C"

However that is lots of work (unless you have a minimual number of functions) and as mike pointed out, it is really for no benefit.  Using a .def file isn't an improvement over the _declspec(dllexport) method unless you need to export at specific ordinals.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Well, the DEF file offers more flexability than just specific ordinals. NONAME, for example, and DATA.

B ekiM


0
 

Author Comment

by:sccheung
Comment Utility
Comment 1 (Monday, June 29 1998 - 08:18PM PDT):
If I use the GetProcAddress(), I can write a piece of code which reads a text file which contain the name of all of the member functions and use a while loop in that piece of code to get do all GetProcAddress(). That may not be tedious as I can copy all of the member function names from the header file. But the problem is how to use GetProcAddress() in the case of classes and can I still use the _declspec() to export in this case. All the books I've got only tell me how to use GetProcAddress to import an independent function but not member functions of a class. Therefore, I don't know how to deal with the problems that appear when importing member functions. e.g. do I have to import the member variables, do I write GetProcAddress(mydll,"myclass.myfunc") or just GetProcAddress(mydll,"myfunc"), how to declare the functions variables(able to maintain the class structure)?

Oh! My father've just told me to go to bed. I've got to continue replying to other comments tomorrow. Sorry for this delay!
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> That may not be tedious as I can copy all of the member function names from the header file.
The problem is that the names in the header file aren't the names exported.  Then names get decorated.  They get a bunch of characters appended to the end of them that "discribe" the procedure's parameters.  Those are the names you need.  There are ways of getting them, but I don't think that matters anyways as I will explain next.

You are talking about using GetProcAddress() to get the procedures from the dll.  Why?  If new procedures have been added to the Dll, you don't know what they are for, so you can't call them anyway.  Your program can only work with the procedures that were there at the time the program was written.  Thus you can just use "GetProcAddress() for the specific names you know about at the time the program was compiled, no need to get those names from another source, like a text file.

Finally, the whole reason this issue seems to have come up is that you are worried about handling changes in classes.  However if a class changes, in general you still aren't going to be able to use GetProcAddress() to your advantage, because you can't call a non-static member function with a ordinary function pointer.  (You probably can get around that with some type casting, but that would be dangerious)  Besides the class may have changed size or may have new virtual functions etc.  so the objects created by the EXE could be tottally incompatible with those created by the DLL.  

The only way to make this work safely is two have the DLL create  the objects and return untyped pointers (handles) to them for the EXE to use.  The EXE could manipulate the objects by calling an ordinary (not a member) function in the DLL and specifying the pointer to the object.  

That is not a fun design.  You are better of just recompiling the EXE and the DLL.
0
 

Author Comment

by:sccheung
Comment Utility
Do you mean I can use ordinary functions to manipulate the class in the EXE? If I changed the class, I just change the implementations of the ordinary functions. That's good. I'm going to use this solution.
0
 

Author Comment

by:sccheung
Comment Utility
Do you mean I can use ordinary functions to manipulate the class in the EXE? If I changed the class, I just change the implementations of the ordinary functions. That's good. I'm going to use this solution.
0
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
Comment Utility
>> Do you mean I can use ordinary functions to manipulate the class in the EXE?

Yes and no.  When the EXE needs to manipulate the class, the EXE calls an ordinary (non-class) function from the DLL and specifies a pointer to object in one of the parameters (first would be typical)  Then the DLL manipulates the object, probably by using a member function.  Note that these functions that the EXE calls (interface functions) will usually use (void *) pointers to point to the object, thus the EXE doesn't actually know what type of object it is pointing to.

Do you understand the implications of the solution?  It means the DLL is object oriented and has all those wonderful OOP advantages.  The EXE or DLL that uses this DLL, will not be object oriented (at least not in the use of these functions).  Thus they don't get the advantages of OOP.  Depending on your needs that may be acceptible.  

Does that work for you?
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now