?
Solved

Is it possible to use both explicit linking and implicit linking at  the same time?

Posted on 2003-03-11
5
Medium Priority
?
346 Views
Last Modified: 2008-03-04
I have got an application which allows me to dynamically link up to various DLLs. I need to modify one cpp source file, which belong to a certain project that compiles into a dll for run-time loading, so that it links up with another dll implicitly. Is this method possible? If yes how do I go about doing it?

Currently, I have tried including the code of the implicitly linked dll in the cpp file that I mentioned. It seems to me that it is able to linked to the implicit dll, however, certain functions in the implicit dll that is suppose to provide some updating, doesn't seem to work.

Please help me

Thank you
 
0
Comment
Question by:Hennesy79
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 12

Expert Comment

by:Salte
ID: 8110650
Perhaps it answers your question that each DLL is independent of other DLLs as far as how you link them. The only exception to this is that if a DLL requires other DLLs then those must be present before you can load that DLL. If it is implicitely then the system will take care of loading them in a sequence so that if A require B then B is loaded before A.

If you do explicit linking it is best done if the DLL in question is not dependent on other DLLs or on DLLs you already have loaded in. Not sure if the system can support automatic loading of "extra" DLLs that are required by the one you're loading, somehow I doubt that it is so smart. It possibly also depend on platform.

So yes, your program can implicitely link to some DLLs and still load as many additional DLLs as you please as long as there's room for them in your virtual memory - that memory is quite large so I don't think that should be a problem.

Just use LoadLibrary() or LoadLibraryEx() on windows or the dlload() function on Unix or Linux to load the DLL then use the functions GetProcAddress() on windows or dlsym() on Unix or Linux to get the address of the function.

Be aware that C++ mangles names so the name argument given to GetProcAddress() or dlsym() is not the name in the C++ code. Check with some tool that display linker names for the name argument given to dlsym() or GetProcAddress().

I would also strongly suggest that you only export plain C functions from a DLL:

class X {
private:
   .....
public:
   .....

   int F() const;
};

extern "C" {
   int __declspec(dllexport) __stdcall X_F(const X * xp);
}


int X_F(const X * xp)
{
   return xp -> F();
}

It is better to export X_F than to export F directly. Stay away from member functions when exporting out of the DLL.

X_F is a C function due to the extern "C" declaration and so it is not mangled and so you can:

int __stdcall (* fptr)(const X * xp);

fptr = (int __stdcall (*)(const X *))GetProcAddress("X_F");

int v = fptr(xptr);

To get the value.

Note that calling the member function directly is very difficult if not impossible. I have assumed Windows style when using the __stdcall. All DLL functions exported from windows DLLs should normally be _stdcall unless you have to use _cdecl. This is because __stdcall is available for all languages and not just C or C++. The Win32 functions themselves are declared as __stdcall and so every language on windows platform must support the ability to call a __stdcall function.

The only reason why you can't use __stdcall is if the function has a varying number of arguments such as printf(). Such a function cannot use __stdcall and must use __cdecl. __cdecl is the default for C so if you specify no calling convention __cdecl is what you get (unless you set an option to set another default).

Note that Borland C++ also uses the __fastcall calling convention which is neither __stdcall nor _cdecl but is a third and incompatible calling convention. Don't use __fastcall unless you call a borland function and it is only borland code that will ever call it.

Overall __stdcall is the most compatible and widely spread on windows platform use it unless you have a good reason not to.

Of course, all this is for the exported functions. Functions declared in the internal functions that aren't exported can be anything you want, they are not visible anyway.

Alf
0
 

Author Comment

by:Hennesy79
ID: 8115924
Does your second paragraph, means that it is best to avoid linking up dll implicitly within a explicitly linked dll which is loaded at run-time?

If that is the case, are you saying that the best way is to linked up the dll residing in the explicit dll, explicitly also?

Forgive my ignorance.
Thank you for your advice.  
0
 
LVL 12

Accepted Solution

by:
Salte earned 600 total points
ID: 8117814
In the second paragraph I raise a concern if DLL A depends on DLL B. If you load or attempt to load DLL A without having loaded DLL B your OS may do one of two things:

1. It may just state that there are unresolved external references and refuse to load the DLL.

2. It may see that you need to load DLL B also and load it first without you explicitely requesting it.

Chances are that your OS choose strategy 1. In that case everyone who use your DLL must remember to load DLL B before they load your DLL, that can be troublesome.

It is better if the DLL you load does not refer to external DLL's other than those that you know the program already has. Some DLLs are unavoidable, such as Kernel32.exe, user32.exe and gui32.exe (they are DLLs even if their extension is .exe - the .exe here is historic, they are really DLLs) but those DLLs are always available anyway and you can trust that they are there.

The MSVC's own runtime library MSVCRT.DLL or whatever it's called is also a safe bet that you probably can use, especially if the program uses the dynamic library instead of static library.

Other DLLs on the other hand is not so safe and as a general rule you should stay away from having your DLL require them.

If your DLL require any other DLLs you should probably have a .LIB which handles loading those DLLs first and then loading your own DLL after.

Another way is to let your DLL also use LoadLibrary to refer to those other DLLs. That way you can load them yourself during DllMain(). So if your DLL require a B.DLL then your DllMain() can do a LoadLibrary("B.DLL") and initialize the linking. This way, the user only have to load your DLL and is unaware that you also use other DLLs.

Alf
0
 

Author Comment

by:Hennesy79
ID: 8124754
Thank you for your explanation. I have got a better understanding of the picture now.

If it is ok, can you give me some advice on what I should do on my current situation?

As what I have discribed earlier, I need to load a dll at run-time, which automatically loads another dll. The problem that I am facing now is that, the linked dll from the loaded one, need to have some continuously changing input from the program that is running. But even though I tried linking the latter dll explicitly from the loaded one, it still doesn't seem to work.

Is it likely that this method cannot work for what I am doing or is it more possible to be some linking errors, or some code that I have left out?

Thank you for your advice.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8133444
>> the linked dll from the loaded one, need to have some continuously changing input from the program that is running.

What does this mean?

You can provide a exported proc that will pass data from the first DLL on to the implicitly-linked DLL.  Then the EXE can just call that one.

Take a few minutes to decribe in specific detail what you are trying to do.  Or more importantly, why you are trying to do this -- what problem are you trying to avoid... that sort of thing.

-- Dan
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

764 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