patterncppMinor
Calling a function from a dynamically loaded DLL
Viewed 0 times
dlldynamicallyfunctionloadedcallingfrom
Problem
I need to implement some functionality of the otherwise monolithic application via DLL that is loaded at runtime. (Think about a customized DLL -- different for each customer.)
The Visual C++ from VS 2013 is used.
The application gets the full name name of the DLL. The function to be called has a fixed name (
I have modified the example from the MSDN doc, and it seems to work. However, I must be sure I did not overlooked something important. Here is the code (simplified) to load the DLL and call the function:
Notice that unlike in the official example that mixes calling a C code in DLL from a C++ function, I do not use
Now, because I want the unmangled name of the function inside the DLL, I need to use
```
#include
#include
The Visual C++ from VS 2013 is used.
The application gets the full name name of the DLL. The function to be called has a fixed name (
convert in my case) and fixed number and type of the arguments (a reference to a constant vector of strings -- see the cref_vs below). This means the function is implemented in C++.I have modified the example from the MSDN doc, and it seems to work. However, I must be sure I did not overlooked something important. Here is the code (simplified) to load the DLL and call the function:
typedef const std::vector & cref_vs;
typedef int(*CONVERTPROC)(cref_vs vs);Notice that unlike in the official example that mixes calling a C code in DLL from a C++ function, I do not use
__cdecl. I guess that this way I can reliably pass a C++ object (like a vector of strings). Is it correct?int call_convert_from_dll(const std::string & dllname,
const std::vector & vs)
{
HINSTANCE hinstLib;
CONVERTPROC convert;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(dllname.c_str());
// If the handle is valid, try to get the function address.
if (hinstLib != nullptr) {
convert = (CONVERTPROC)GetProcAddress(hinstLib, "convert");
// If the function address is valid, call the function.
if (convert != nullptr) {
(convert)(vs);
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
if (!fRunTimeLinkSuccess)
return 1;
return 0;
}Now, because I want the unmangled name of the function inside the DLL, I need to use
extern "C", and it must be exported via __declspec(dllexport). However, I do not want to use __cdecl calling convention:```
#include
#include
Solution
Short answer: No, but I won't hold it against you. ;)
I'd suggest reading up on using C++ with DLLs in a compatible fashion, and would suggest this excellent article as a good place to start. This article also touches on exporting STL types, which your code is doing.
So, the question is, how portable/robust do you need/expect your approach to be? If you need developers from anywhere to be able to plug into your system, stick to a C interface if possible (avoiding STL types -- pass a
Minor code notes...
I'd suggest reading up on using C++ with DLLs in a compatible fashion, and would suggest this excellent article as a good place to start. This article also touches on exporting STL types, which your code is doing.
So, the question is, how portable/robust do you need/expect your approach to be? If you need developers from anywhere to be able to plug into your system, stick to a C interface if possible (avoiding STL types -- pass a
char** across the boundary, and convert that on the C++ side to an STL vector). Otherwise, upgrade to a virtual class based system -- and make sure that you don't directly use STL, but instead use virtual class wrappers for those types as well. Note that this carries on -- e.g., if you want to use an iterator class used by the STL type you're wrapping, you'll need another abstract (iterator) class that your abstract (iterable) class references, so it can get a little ugly.Minor code notes...
fFreeResultis assigned, but never used.
fRunTimeLinkSuccessis not set (after initialization).
- The "convert" string might better be contained in a macro (or a small set of macros), so that your plugin clients can declare a convert function, and you can refer to that function name without the possibility of typo.
- Your example plugin refers to
argcandargvthat don't exist.
Context
StackExchange Code Review Q#48224, answer score: 3
Revisions (0)
No revisions yet.