I have a question for com handling.
I'm using a third party dll which I include through #import, using named_guids as argument. I don't know if I should use another argument or not for proper importing..?
The problem is that there are different versions of the dll. One particular function that I'm using is added in the last version of the dll. So, if a costumer have an older version there is an exception - access violation executing location (some address). I understand that the error is telling me that the function can't be found, but how to catch this exception?
I tried with try-catch(_com_error) - nothing, try-catch(std::exception) - nothing, even try-catch(...) - still nothing.
Can I catch this kind of exception and log the exception and tell the costumer that there is a problem with the dll?
I'm not working with LoadLibrary and GetProcAddress.
The developer of the third party DLL violated a core principle of COM: Interfaces are immutable. This implies that once published, an interface may not change whatsoever. You are seeing the effect of what happens when this rule isn't followed: your call to the non-existent method results in an access violation.
If the COM interface derives from IDispatch, then you have an easy way to check, whether a method exists or not: Use GetIDsOfNames to get the DISPID of the method. If it doesn't exist, the function will return with a DISP_E_UNKNOWNNAME error:
DISPID dispID;
BSTR methodName = SysAllocString(L"MyMethod");
// Check hr return value
HRESULT hr = piDisp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
SysFreeString(methodName);
My COM server implemented in Visual C++ uses a ton of other C++ code. That other C++ code sometimes wraps code in __try-__except and translates structured exceptions into custom C++ exceptions. This part I cannot change.
No method of my COM server should let those exceptions propagate through the COM boundary so it has to catch and translate them into HRESULTs. Those custom C++ exceptions contain the original error code which was obtained during translation - it's something like EXCEPTION_ACCESS_VIOLATION. The question is how I craft an appropriate HRESULT value so that the client has as much information as possible as to what happened (and perhaps decide to restart the server (and itself in case of inproc) after seeing an access violation).
Suppose it was EXCEPTION_ACCESS_VIOLATION which is defined in WinBase.h
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
and the latter is defined in WinNT.h
#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
I could use HRESULT_FROM_WIN32() to translate that code into HRESULT assuming that it was a Win32 error in the first place.
Do I use HRESULT_FROM_WIN32() here or do I use any other way to do the translation?
You are supposed to return HRESULT code, where you choose appropriate code to indicate status of operation. It does not have to be a failure code, but you typically want to show something that satisfies FAILED(...) macro, e.g. E_FAIL, or DISP_E_EXCEPTION or HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION).
It is highly unlikely that callers compare against specific exception-related HRESULT, so specific failure code makes sense rather for diagnostic. Also, as you complete handling the exception before exiting from COM method, there is no need to return specific HRESULT code because no additional actions are required or necessary.
To provide additional information, it is possible to use ISupportErrorInfo, IErrorInfo and friends. Callers can retrieve free text description and many popular environments to this automatically, so for example .NET caller will have this additional information on exception message rather than standard message generated from HRESULT code.
ATL offers AtlReportError to wrap SetErrorInfo API, which also suggests on generating HRESULT code:
... If hRes is zero, then the first four versions of AtlReportError return DISP_E_EXCEPTION. The last two versions return the result of the macro MAKE_HRESULT( 1, FACILITY_ITF, nID ).
I have a DLL given named Lib.ddl. In the dll i have a function named add that takes an integer as a parameter.
Using the windows API and by using the following class.
class WindoswAPI
{
public:
WindowsAPI();//constructor
//helper functions
~WindowsAPI();
private:
}
How do I load this library in the constructor of the class. Extract the function via helper functions, and unload the function in the destructor?
I have looked on the internet for solutions and help but i cant find any.
You should first look at LoadLibraryEx() in order to load the dll in your process, then you can use GetProcAddress() to obtain a pointer to a function by name. Note the HMODULE parameter requested from the second function is returned by the first. You have to carefully know the function signature to invoke it without causing GPFs, so don't be surprised if you have to do some debug before having it working.
First easy thing to check anyway are the return values of both functions: the first one should return something different from zero ( it actually returns the virtual address where the dll is loaded ), if it returns NULL, use GetLastError to have some hints.
The same for GetProcAddress, if it return zero something didn't work, and usually is the incorrect spelling of the function name. As I said before having back an address from GetProcAddress does not guarantee you have finished: you must know perfectly how to call the function. If you need help in discovering which name are exposed from the dll, you will find useful DUMPBIN.EXE, you should have it already available from the Visual Studio Tools command prompt.
When your code finish with the dll, you can try to unload it by using FreeLibrary().
Look at POCO C++ Libraries, it contains very nice crossplatfrom DLL-Loader to avoid hand-written workarounds and boilerplate.
Today I had to define the WIN32_MEAN_AND_LEAN preprocessor macro in a native C++ project because I decided to use boost::asio in it, and without that macro, I get build errors.
Thing is, the error I get now is OleInitialize: identifier not found. According to the MSDN, this function is used to initialize a COM library. My project is not a COM library now, but my partners say it used to be.
In this case, would it be safe to remove the call? The project uses a mix of Win32 serial port functions and boost::asio (gradually, I'll leave just boost::asio). My concern is that OleInitialize might be necessary for some Win32 calls.
This is all it is done with it:
HRESULT hOle = OleInitialize( 0 );
if( !SUCCEEDED( hOle ) )
throw "Could not initialize OLE";
The worst that will happen is COM methods may start failing, if you're still calling some. OleInitialize() calls CoInitialize() internally. Only those functions need this. The base Win32 functions (CreateWindow, CreateFile, etc) do not require this initialization.
If you don't call any COM methods (any of the CoXXX() functions) and you don't call any Ole methods (OleXXX() functions), then you should be fine if you remove it.
You should do a quick search of your code base for COM / OLE functions and make sure you're really not using those technologies anymore. Then you can make a build where you don't do this and test it to see if it still works (you have a suite of test cases, right?).
Have a look at the Docs for other things that may break that you should check on.
Sooooo I'm writing a script interpreter. And basically, I want some classes and functions stored in a DLL, but I want the DLL to look for functions within the programs that are linking to it, like,
program dll
----------------------------------------------------
send code to dll-----> parse code
|
v
code contains a function,
that isn't contained in the DLL
|
list of functions in <------/
program
|
v
corresponding function,
user-defined in the
program--process the
passed argument here
|
\--------------> return value sent back
to the parsing function
I was wondering basically, how do I compile a DLL with gcc? Well, I'm using a windows port of gcc. Once I compile a .dll containing my classes and functions, how do I link to it with my program? How do I use the classes and functions in the DLL? Can the DLL call functions from the program linking to it? If I make a class { ... } object; in the DLL, then when the DLL is loaded by the program, will object be available to the program? Thanks in advance, I really need to know how to work with DLLs in C++ before I can continue with this project.
"Can you add more detail as to why you want the DLL to call functions in the main program?"
I thought the diagram sort of explained it... the program using the DLL passes a piece of code to the DLL, which parses the code, and if function calls are found in said code then corresponding functions within the DLL are called... for example, if I passed "a = sqrt(100)" then the DLL parser function would find the function call to sqrt(), and within the DLL would be a corresponding sqrt() function which would calculate the square root of the argument passed to it, and then it would take the return value from that function and put it into variable a... just like any other program, but if a corresponding handler for the sqrt() function isn't found within the DLL (there would be a list of natively supported functions) then it would call a similar function which would reside within the program using the DLL to see if there are any user-defined functions by that name.
So, say you loaded the DLL into the program giving your program the ability to interpret scripts of this particular language, the program could call the DLLs to process single lines of code or hand it filenames of scripts to process... but if you want to add a command into the script which suits the purpose of your program, you could say set a boolean value in the DLL telling it that you are adding functions to its language and then create a function in your code which would list the functions you are adding (the DLL would call it with the name of the function it wants, if that function is a user-defined one contained within your code, the function would call the corresponding function with the argument passed to it by the DLL, the return the return value of the user-defined function back to the DLL, and if it didn't exist, it would return an error code or NULL or something). I'm starting to see that I'll have to find another way around this to make the function calls go one way only
This link explains how to do it in a basic way.
In a big picture view, when you make a dll, you are making a library which is loaded at runtime. It contains a number of symbols which are exported. These symbols are typically references to methods or functions, plus compiler/linker goo.
When you normally build a static library, there is a minimum of goo and the linker pulls in the code it needs and repackages it for you in your executable.
In a dll, you actually get two end products (three really- just wait): a dll and a stub library. The stub is a static library that looks exactly like your regular static library, except that instead of executing your code, each stub is typically a jump instruction to a common routine. The common routine loads your dll, gets the address of the routine that you want to call, then patches up the original jump instruction to go there so when you call it again, you end up in your dll.
The third end product is usually a header file that tells you all about the data types in your library.
So your steps are: create your headers and code, build a dll, build a stub library from the headers/code/some list of exported functions. End code will link to the stub library which will load up the dll and fix up the jump table.
Compiler/linker goo includes things like making sure the runtime libraries are where they're needed, making sure that static constructors are executed, making sure that static destructors are registered for later execution, etc, etc, etc.
Now as to your main problem: how do I write extensible code in a dll? There are a number of possible ways - a typical way is to define a pure abstract class (aka interface) that defines a behavior and either pass that in to a processing routine or to create a routine for registering interfaces to do work, then the processing routine asks the registrar for an object to handle a piece of work for it.
On the detail of what you plan to solve, perhaps you should look at an extendible parser like lua instead of building your own.
To your more specific focus.
A DLL is (typically?) meant to be complete in and of itself, or explicitly know what other libraries to use to complete itself.
What I mean by that is, you cannot have a method implicitly provided by the calling application to complete the DLLs functionality.
You could however make part of your API the provision of methods from a calling app, thus making the DLL fully contained and the passing of knowledge explicit.
How do I use the classes and functions in the DLL?
Include the headers in your code, when the module (exe or another dll) is linked the dlls are checked for completness.
Can the DLL call functions from the program linking to it?
Yes, but it has to be told about them at run time.
If I make a class { ... } object; in the DLL, then when the DLL is loaded by the program, will object be available to the program?
Yes it will be available, however there are some restrictions you need to be aware about. Such as in the area of memory management it is important to either:
Link all modules sharing memory with the same memory management dll (typically c runtime)
Ensure that the memory is allocated and dealloccated only in the same module.
allocate on the stack
Examples!
Here is a basic idea of passing functions to the dll, however in your case may not be most helpfull as you need to know up front what other functions you want provided.
// parser.h
struct functions {
void *fred (int );
};
parse( string, functions );
// program.cpp
parse( "a = sqrt(); fred(a);", functions );
What you need is a way of registering functions(and their details with the dll.)
The bigger problem here is the details bit. But skipping over that you might do something like wxWidgets does with class registration. When method_fred is contructed by your app it will call the constructor and register with the dll through usage off methodInfo. Parser can lookup methodInfo for methods available.
// parser.h
class method_base { };
class methodInfo {
static void register(factory);
static map<string,factory> m_methods;
}
// program.cpp
class method_fred : public method_base {
static method* factory(string args);
static methodInfo _methoinfo;
}
methodInfo method_fred::_methoinfo("fred",method_fred::factory);
This sounds like a job for data structures.
Create a struct containing your keywords and the function associated with each one.
struct keyword {
const char *keyword;
int (*f)(int arg);
};
struct keyword keywords[max_keywords] = {
"db_connect", &db_connect,
}
Then write a function in your DLL that you pass the address of this array to:
plugin_register(keywords);
Then inside the DLL it can do:
keywords[0].f = &plugin_db_connect;
With this method, the code to handle script keywords remains in the main program while the DLL manipulates the data structures to get its own functions called.
Taking it to C++, make the struct a class instead that contains a std::vector or std::map or whatever of keywords and some functions to manipulate them.
Winrawr, before you go on, read this first:
Any improvements on the GCC/Windows DLLs/C++ STL front?
Basically, you may run into problems when passing STL strings around your DLLs, and you may also have trouble with exceptions flying across DLL boundaries, although it's not something I have experienced (yet).
You could always load the dll at runtime with load library