I have some general purpose functions defines in my exe file like Log(char* str). This function takes a string as an input from the caller and writes it to the logfile defined for that application. Now I want to write DLL code which will include a function to upload a file to a server.
The objective is to import the upload function from the DLL into the exe and use it. However, if any error is encountered, then the upload function must call the Log(char* str) function to write the error into the log file.
The trouble is that this DLL needs to be used in multiple applications and each app will have a different logfile at a different location. I want to write the DLL in such a way that it calls the corresponding Log(char* str) defined in the application. Similarly I have some other functions that are application-specific and cannot be included in the DLL beforehand.
How can I write such DLL code where it only knows the function prototype, but not the function definition, which resides inside the exe?
Have a function in your DLL that the .exe can call, passing in a function pointer to your Log function. Inside the DLL, store that function pointer and use it when you need to log things.
If there is more than one such function you need to pass to your DLL, consider using a struct to store all the relevant function pointers.
Here's a good tutorial on function pointers: The function pointer tutorial
To keep this interface simple, I would highly recommend keeping all these "customizable" functions in plain C, at least as a starting point. Dealing with pointer-to-member functions and passing C++ objects around through C wrappers is error-prone. (But doable.) Or stick with C++ all round.
Here's a short example. In a common header, put something like this:
typedef void (*logfunc)(char const*);
to simplify passing around the customized function pointer.
In your DLL code, you could then have:
logfunc cust_log;
void dll_init_logging(logfunc l)
{
cust_log = l;
}
void dll_do_something()
{
cust_log("hello");
}
Modify that to make these functions exportable if necessary on your platform.
Then from your main code, all you need to do (assuming you're loading the DLL and making the exported functions available to your .exe with their original name) is:
void logit(char const* str)
{
printf("Log: %s\n", str);
}
int main (int argc, char const *argv[])
{
// load the DLL
dll_init_logging(logit);
...
dll_do_something();
...
return 0;
}
Related
While working on a C++/CLI project to wrap a native C++ DLL, I've come across a native function that takes in a std::string. Something like the following:
class NativeApi
{
public:
ErrorCode readFile(std::string filename = "path.csv");
};
Inside my managed wrapper implementation I allocate a new instance of the native class and call this function:
ref class ManagedApi
{
private:
NativeApi *api;
public:
ManagedApi(): api(new NativeApi()) { }
void Read()
{
api->readFile("apath.csv") // or with nothing to use default value
}
}
When I run this, I get the MDA PinvokeStackImbalance complaining that this call has unbalanced the stack. I was surprised, since the only other time I ever got this MDA was from C# when calling conventions didn't match. I never saw this happen with C++/CLI, where presumably all the matching is done automatically by the compiler.
Has anyone ever saw this before? Googling came up empty. I've looked at the DLL signature and it looks something like:
?readFile#NativeApi##QAE?AW4ErrorCode##V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z
This tells me that the function is there, and takes as a sole argument a basic_string, which should match the standard std::string typedef.
No idea what could possibly have gone wrong. I can make other calls to the native API that do not involve strings perfectly fine.
It is likely that there's a difference between the definition of std::string that you're using vs. what was used to compile the native C++ DLL. Even if the definitions are the same, the native DLL probably isn't using the same version of the C runtime as you are, so when your DLL allocates memory for the std::string, the Native DLL will try to call delete on it (when the string is destroyed at the end of the readFile method), and that call to delete will go to a different heap than was used to allocate the object!
If you want to make this work, you'll have to use the exact same version of the compiler as was used on the native DLL. Note that you'll be limited to the Release build of your project, as you don't have a native DLL that was compiled with the debug runtime.
The proper fix to this problem is to use raw types when calling across DLL boundaries (in this case, wchar_t*). If you can request a change to the native DLL, I would do that. If only raw types are used, then there's no issue with using different runtimes, and everything works the way it should.
This might seem like an odd question, but I was wondering if it were possible with any sort of hack to call static functions from another file without explicitly using extern or anything like that. Perhaps by calling the memory address of the function directly or something.
Basically what I want to do is create a test framework which can call into any function by specifying the function, file and function parameters.
So something like this structure:
component/
component.c
static int foo(int a){return a/2;}
int bar(){ return 4;}
unit_tests/
main.c
int val = component.c::foo(4) * bar();
Even better would be if I could do this at runtime by injecting into the memory address of the function or something. I'm not entirely sure about if this would be executable on linux though, or if I'd hit security issues.
Perhaps something similar to this, and have a block of code in my component process to interpret runtime calls and translate to the correct function address: Calling a function through its address in memory in c / c++
You can use function pointers to static functions.
For test frameworks, note that some existing test frameworks in C use the trick to force you to use STATIC instead of the static specifier and STATIC is a macro defined (by the framework) to either nothing or static if you are in test mode or not to specify the correct linkage.
In my interpreter I have built-in functions available in the language like print exit input, etc.
These functions can obviously be accessed from inside the language. The interpreter then looks for the corresponding function with the right name in a vector and calls it via a pointer stored with its name.
So I gather all these functions in files like io.cpp, string.cpp, arithmetic.cpp. But I have to add every function to the function list in the interpreter in order for it to be found.
So in these function files I have things like:
void print( arg )
{
cout << arg.ToString;
}
I'd add this print function to the interpreter function list with:
interpreter.AddFunc( "print", print );
But where should I call the interpreter.AddFunc?
I can't just put it there below the print function as it has to be in a function according to the C++ syntax.
Where and how should all the functions be added to the list?
In each module (io, string, etc.), define a method that registers the module with the interpreter, e.g.:
void IOModule::Register(Interpreter &interpreter) {
interpreter.AddFunc( "print", print );
//...
}
This can also be a normal function if your module is not implemented in a class.
Then in your application's main initialization, call the register method of all modules.
This approach helps keep things modular: The main application initialization needs to know which modules exist, but the details of which functions are exported are left to the module itself.
The simplest is to keep a map of function names to function pointers and load that at program startup. You already have the functions linked into the interpreter executable, so they are accessible at the time main() is called.
You can also come up with a scheme where functions are defiled in the dynamic libraries (.dll or .so depending on the platform) and some configuration file maps function names to libraries/entry points.
Is everything included in every interpreter? If so, I would recommend adding it either in a constructor (assuming the interpreter is an object) or an init method.
If not, you may want to consider adding an "include" type directive in your language. Then you do it when you encounter the include directive.
I'm trying to explicitly link with a DLL. No other resources is available except the DLL file itself and some documentation about the classes and its member functions.
From the documentation, each class comes with its own
member typedef
example: typedef std::map<std::string,std::string> Server::KeyValueMap, typedef std::vector<std::string> Server::String Array
member enumeration
example: enum Server::Role {NONE,HIGH,LOW}
member function
example: void Server::connect(const StringArray,const KeyValueMap), void Server::disconnect()
Implementing the codes from google search, i manage to load the dll can call the disconnect function..
dir.h
LPCSTR disconnect = "_Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20";
LPCSTR connect =
"_Java_mas_com_oa_rollings_as_apiJNI_Server_1connect#20";
I got the function name above from depends.exe. Is this what is called decorated/mangled function names in C++?
main.cpp
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include "dir.h"
typedef void (*pdisconnect)();
int main()
{
HMODULE DLL = LoadLibrary(_T("server.dll"));
pdisconnect _pdisconnect;`
if(DLL)
{
std::cout<< "DLL loaded!" << std::endl;
_disconnect = (pdisconnect)GetProcAddress(DLL,disconnect);
if(_disconnect)
{
std::cout << "Successful link to function in DLL!" << std::endl;
}
else
{
std::cout<< "Unable to link to function in DLL!" << std::endl;
}
}
else
{
std::cout<< "DLL failed to load!" << std::endl;
}
FreeLibrary (DLL);
return 0;}
How do i call (for example) the connect member function which has the parameter datatype declared in the dll itself?
Edit
more info:
The DLL comes with an example implementation using Java. The Java example contains a Java wrapper generated using SWIG and a source code.
The documentation lists all the class, their member functions and also their datatypes. According to the doc, the list was generated from the C++ source codes.(??)
No other info was given (no info on what compiler was used to generate the DLL)
My colleague is implementing the interface using Java based on the Java example given, while I was asked to implement using C++. The DLL is from a third party company.
I'll ask them about the compiler. Any other info that i should get from them?
I had a quick read through about JNI but i dont understand how it's implemented in this case.
Update
i'm a little confused... (ok, ok... very confused)
Do i call(GetProcAddress) each public member function separately only when i want to use them?
Do i create a dummy class that imitates the class in the dll. Then inside the class definition, i call the equivalent function from the DLL? (Am i making sense here?) fnieto, is this what you're showing me at the end of your post?
Is it possible to instantiate the whole class from the DLL?
I was trying to use the connect function described in my first post. From the Depends.exe DLL output,
std::map // KeyValueMap has the following member functions: del, empty, get, has_1key,set
std::vector // StringArray has the following member functions: add, capacity, clear, get, isEMPTY, reserve, set, size
which is different from the member functions of map and vector in my compiler (VS 2005)...
Any idea? or am i getting the wrong picture here...
Unless you use a disassembler and try to figure out the paramater types from assemly code, you can't. These kind of information is not stored in the DLL but in a header file coming with the DLL. If you don't have it, the DLL is propably not meant to be used by you.
I would be very careful if I were you: the STL library was not designed to be used across compilation boundaries like that.
Not that it cannot be done, but you need to know what you are getting into.
This means that using STL classes across DLL boundaries can safely work only if you compile your EXE with the same exact compiler and version, and the same settings (especially DEBUG vs. RELEASE) as the original DLL. And I do mean "exact" match.
The C++ standard STL library is a specification of behavior, not implementation. Different compilers and even different revisions of the same compiler can, and will, differ on the code and data implementations. When your library returns you an std::map, it's giving you back the bits that work with the DLL's version of the STL, not necessarily the STL code compiled in your EXE.
(and I'm not even touching on the fact that name mangling can also differ from compiler to compiler)
Without more details on your circumstances, I can't be sure; but this can be a can of worms.
In order to link with a DLL, you need:
an import library (.LIB file), this describes the relation between C/C++ names and DLL exports.
the C/C++ signatures of the exported items (usually functions), describing the calling convention, arguments and return value. This usually comes in a header file (.H).
From your question it looks like you can guess the signatures (#2), but you really need the LIB file (#1).
The linker can help you generate a LIB from a DLL using an intermediate DEF.
Refer to this question for more details: How to generate an import library from a DLL?
Then you need to pass the .lib as an "additional library" to the linker. The DLL must be available on the PATH or in the target folder.
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