Solved

Exporting class from a dll with a .def file

Posted on 1998-06-29
12
1,219 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
ID: 1166889
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
ID: 1166890
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
ID: 1166891
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
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 
LVL 2

Expert Comment

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

Expert Comment

by:danny_pav
ID: 1166893
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
ID: 1166894
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
 
LVL 11

Expert Comment

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

B ekiM


0
 

Author Comment

by:sccheung
ID: 1166896
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
ID: 1166897
>> 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
ID: 1166898
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
ID: 1166899
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
ID: 1166900
>> 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

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
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.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

777 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