Link to home
Start Free TrialLog in
Avatar of ericcnc
ericcnc

asked on

DLL correctness

I need some help on a MFC shared dll.  I just want to make sure I'm doing this correctly.

A synopsis on what I'm doing.
1.)Adding classes to a dll that will be exported to a exe and be used internal to dll.
2.)Adding variables that will be global, and used both internal to dll and by the exe.
3.)Adding functions that will be global, and used both internal to dll and by the exe.
4.)MFC is in the functions used.


first thing I did was made a dll using the App wizard
Use MFC in a shared dll(I think this one will also ship out MFC with the dll)

((NOTE: I then added all the classes into the dll by coping the *.h, and *.cpp into the project(about 15 in all)
and put the AFX_CLASS_EXPORT))
Example:

class AFX_CLASS_EXPORT CPoints  
{
public:
     CPoints();
     virtual ~CPoints();
     CPoints& operator=(CPoints &apt);
     double x, y;
};

Next, I made a header file and put it into the DLL (Dllexports)

Then I added the following:

((NOTE: I added the below because I wanted to make just one header file but for some reason the *.exe didn't accept the
acknowledge dllimport comment???, I think because it was defined internal to the dll but I'm not sure????))

#if!defined(Dllexports_h)
#define Dllexports_h
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif // !defined(Dllexports_h)

//test varible
DLL     bool quicker;

//test collections
DLL CArray<int,int>loop_buckets_array;
DLL CArray<CIntersect,CIntersect&>intersection_array;


//tolerences type functions for testing
DLL double fround(double f1);



Summary for the dllexports file
(Then added the appropriate class includes for the collections)



((Then in the DllApp.cpp file for the dll I added the function in the global space))
example:

(NOTE: I didn't put it into the DLLApp class
 because I want it to be global i.e. double CDllApp::fround(double f1)  not sure in this???)

double fround(double f1)
{
     f1*=10000;
          double  floor_f = floor(f1);
     if(floor_f==-1)
          floor_f=0;
     if((f1 - floor_f) > 0.5)
          floor_f++;

     floor_f/=10000;
     return floor_f;
}


((Then I complied and linked to the exe.))

((I then made a import header because the export header didnt work in the exe
it looks like this:))


#if ! defined(dllimports_h)
#define dllimports_h
#define DLL __declspec(dllimport)

DLL     bool quicker;

//collections
DLL     CArray<int,int>loop_buckets_array;
DLL     CArray<CIntersect,CIntersect&>intersection_array;

//tolerences type functions
DLL double fround(double f1);

#endif //! defined(dllimports_h)

((I complied and no errors and it runs...))

((I wanted a DLL guru's opinion on what I did and to see if this is correct programming
principles for a dll.  Is the above correct?))




Avatar of christophm
christophm

You must use an extension DLL - shared DLL can't export classes.

Extension DLLs need to dynamically link to the MFC library so the CLIENT program(s) must be specified to dynamically link to the MFC library too.

The client program(s) and DLL must be built with the same version of the MFC library.

If the DLL is to be used by anything 'screwy' (anything other than C++ callers; like VB for instance) then you should not use an extension DLL and attempt to export classes you should stay with a shared DLL (with MFC) or a plain old C DLL (or my favorite an automation component).

All the above from "Inside Visual C++", David Kruglinski, Microsoft Press.

good luck - chris miller
Avatar of ericcnc

ASKER

I'm not sure what you mean?

The current dll does export the classes above,
and everything does work or seems to work fine.
( I was under the impression that you use a extension class if your classes are derived from the object class which none of my classes are.. they are all custom classes)

I'm just concerned that I'm doing something wrong a programming screw up.  This dll is currently going to be used just by MFC and C++ stuff currently.  BUT, VB could be possible.

Another thing is that, if my dll is going to be used by somebody and my code ie the fround function for example, is internal to my dll and if I am debugging in my exe, and somebody selects the (jump into function command) in the debugger will they then be inside my dll such that they actually see code?

I just want a Dll guru to look over this and give his opinion and tell me of some potential problems.

BUT again currently this dll does work.

How do you ensure Dll security for functions--?
Avatar of ericcnc

ASKER

Also, I had to add the header files into the orginal exe of the classes that are in the Dll. Is that correct
Avatar of DanRollins
ericcnc,
Most of these questions are easily answered by simply building a few DLLs and trying a few things.  In the time you have spent here, you could be a DLL genius from using trial-and-error testing techniques.

>>will they then be inside my dll such that they actually see code?
Only if you ship your source code with your project.  Is that your intention?

>>and tell me of some potential problems
1) You need to use
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
on entry into any function -- including class ctors and dtors.  

2) I am not a C++ purist, but global values and even global fns can end up causing unexpected headaches when you use them in a multithreaded environment.  It is nearly always as easy to wrap a thin "object" around them so that each caller can construct and destruct (or retain) its own copy.  For truly global objects (to be used by multiple threads simultaneously), you need to provide a serialization mechanism such as CSemaphore.

3) Avoid STL containers in DLLs.  The MFC containers, such as CArray<int,int> will be ok (if you follow #1, above).

>>How do you ensure Dll security for functions--?
What do you mean?

=-=-=-=--==--==--=
Incidently, I don't think that you need to make an MFC Extension DLL as suggested by christophm.  That is mostly used to extend MFC classes (for instance, if you want to provide a CSuperString so that other programmers can use it in thier projects).

-- Dan
Avatar of ericcnc

ASKER

Dan,
>>will they then be inside my dll such that they actually see code?
Only if you ship your source code with your project.  Is that your intention?

No that is not my intention, I just want to make a nice little secure dll.

My dll is a regurlar shared dll with MFC so do I need those manage state macros? I thought I read in the help stuff that that is only used by dynamically linked stuff?
The dll seems to be working fine without them.


For the security I mean since I made my function exported to the exe, I found that if I select the step into command in debugging I was then inside my function.  Is there a way to not allow you to get inside the function but allow it to be used. Or is reason it did this was because it had the source code on the same machine or because I had the dll open at the same time the exe was being debugged???


The reason I want to use global values is because for example I have a line intersection function whose endpoints need to be returned to four different functions for use in trimming and such.  And I notice by playing around that if I put my functions into the classes and called them the system tended to slow down more noticably.?

Is it typically to supply the header files to a exe that uses the dll?


Above all I guess what your saying is to mess around and play with it because thats ultimately what you will need to do to learn it.? :)

ASKER CERTIFIED SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ericcnc

ASKER

Dans incite to dll creation is refreshing, it allows for up and coming developers such as myself to understand things that the countless books briefly touch upon.