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.
Related
I need to load a DLL file in Lua to connect different APIs. I know that C type dlls can be loaded, but what I have is a dll file produced in C++.
The code (in C++) that produced this library was of the form:
// MyAPI.h
namespace MyAPI
{
public class MyFirstClass
{
public:
MyFirstClass();
void performSomeMethod(int arg);
}
}
which then produced the dll file MyAPI.dll. When I now try to import this in Lua, using:
require "MyAPI"
it immediately gives the error: error loading module 'MyAPI' from file '.\MyAPI.dll': The specified procedure could not be found. I do not understand what this means, or how to get rid of it. Can C++ libraries in general not be included by Lua (i.e. should I write another C wrapper?) or is there a way to do this?
Yes, it can be done. Expose a C-function loader luaopen_MyAPI, where you can call a function that uses any kind of C++ Lua Wrapper, such as LuaBridge, LuaBind or others. If your calls in C++ don't conform to the rules of the bindings, such as lifetime management, passing objects by value, etc, you might need to wrap the classes into bindable classes.
For an example see pugilua
pugilua_lib.h - module loader API
pugilua_lib.cpp - wrapper classes and a LuaBridge binding
pugilua.cpp - calling the bindings from the module loader
You need to export a C function named luaopen_ MyAPI that follows the C-Lua API. The rest of the code can be C++.
My understanding is that you will need to have a C wrapper with a C entry point rather than a C++ entry point. C++ does name mangling so it can change dynamically depending on the compiler as well as the method signature, etc.
Here is Anatomy of a Lua to C Call which you may find helpful.
Also see this stack overflow discussion on what goes on with dll loading.
And here is another stack overflow discussion on require and dll loading.
This is a brief post on the name mangling problem.
I would like to accomplish a simple task:
I want to produce a C++/CLI lib that calls some .NET routines, and exposes 1 static method that I can call from purely native C++ app. I want to statically link to that lib from my native app. The signature of the method that the native C++ app would call should be
void (unsigned char* data, int length, _TCHAR* args[])
I am pretty new to C++/CLI and C++ in general. So, can you please help me and answer these questions:
For my tiny C++/CLI project, I assume the type needs to be class library with lib as output, targeting vc9 runtime (so that I can be sure it is available on end users PCs). Am I correct in this assumption?
Can you provide an example of the outline of the method with that signature I will need to write in my C++/CLI project. In particular how should I do conversion to CLR types properly (i.e. byte[], int32, and string)? And how do I decorate that method with something like "extern "C" __declspec(dllexport)" to make this method callable from my native C++ app?
How would I separate the code between cpp and h files in C++/CLI properly?
Finally how would I actually call it from my native app once I add lib reference?
Thank you.
Class library: correct, but you'll also need to change your project's configuration type from Dynamic Library to Static Library. I'm not sure what you mean by 'targeting vc9 runtime' – you need to target the same runtime as the native code that will be using your static library.
Since this is a static library, no __declspec(dllexport) is needed. If you want to know how to do conversion to .NET types, you'll need to post what your code is actually doing. In general, you'll want Marshal::Copy to copy a C-array into a .NET array, and marshal_as<> to copy C-strings into .NET strings, but there's still the question as to whether that data is intended to be mutable and needs to be marshaled back to native types before returning...
The exact same as in C++ – declaration in a header, definition in a source file.
The exact same as any other function – #include the header containing the declaration and call the function.
Consider this synthetic example. I have two native C++ projects in my Visual Studio 2010 solution. One is console exe and another is lib.
There are two files in lib:
// TImage.h
template<class T> class TImage
{
public:
TImage()
{
#ifndef _LIB
std::cout << "Created (main), ";
#else
std::cout << "Created (lib), ";
#endif
std::cout << sizeof(TImage<T>) << std::endl;
}
#ifdef _LIB
T c[10];
#endif
};
void CreateImageChar();
void CreateImageInt();
and
// TImage.cpp
void CreateImageChar()
{
TImage<char> image;
std::cout << sizeof(TImage<char>) << std::endl;
}
void CreateImageInt()
{
TImage<int> image;
std::cout << sizeof(TImage<int>) << std::endl;
}
And one file in exe:
// main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
TImage<char> image;
std::cout << sizeof(TImage<char>) << std::endl;
CreateImageChar();
CreateImageInt();
return 0;
}
I know, I shouldn't actually do like this, but this is just for understanding what is happening. And that's, what happens:
// cout:
Created (main), 1
1
Created (main), 1
10
Created (lib), 40
40
So how exactly this happened, that linker overrides lib's version of TImage<char> with exe's version of TImage<char>? But since there is no exe's version of TImage<int>, it preserves lib's version of TImage<int>?.. Is this behavior standardized, and if so, where can I found the description?
Update: Explanations of the effect given below are correct, thanks. But the question was "how exactly this happened"?.. I expected to get some linker error like "multiply defined symbols". So the most suitable answer is from Antonio Pérez's reply.
Template code creates duplicated object code.
The compiler copies the template code for the type you provide when you instance the template. So when TImage.cpp is compiled you get object code for two versions of your template, one for char and one for int in TImage.o. Then main.cpp is compiled and you get a new version of your template for char in main.o. Then the linker happens to use the one in main.o always.
This explains why your output yields the 'Created' lines. But it was a little bit puzzling to see the mismatch in lines 3, 4 regarding object's size:
Created (main), 1
10
This is due to the compiler resolving the sizeof operator during compile-time.
I am assuming here that you are building a static library, because you do not have any __decelspec(dllexport) or extern "C" in the code. What happens here is the following. The compiler create an instance of TImage<char> and TImage<int> for your lib. It also creates an instance for the your executable. When the linker joins the static library and the objects of the executable together duplicate code gets removed. Note here that static libraries are linked in like object code, so it does not make any difference if you create one big executable or multiple static libraries and an executable. If you would build one executable the result would be dependent on the order the objects are linked in; aka "not defined".
If you change the library to a DLL the behavior changes. Since you are calling over the boundary of a DLL, each needs their copy of TImage<char>. In most cases DLLs behave more as you would expect a library to work. Static libraries are normally just a convenience, so you need not put the code into your project.
Note: This only applies on Windows. On POSIX systems *.a files behave like *.so file, which creates quite some head aches for compiler developers.
Edit: Just never ever pass the TImage class over a DLL boundary. That will ensure a crash. That is the same reason why Microsoft's std::string implementation crashes when mixing debug and release builds. They do exactly what you did only with the NDEBUG macro.
The compiler will always instantiate your template when you use it - if the definition is available.
This means, it generates the required functions, methods etc. for the desired specialization and places them in the object file. This is the reason why you either need to have the definition available (usually in a header file) or an existing instantiation (e.g. in another object file or library) for the specific specialization that you are using.
Now, when linking, a situation might occur which is usually not allowed: more than one definition per class/function/method. For templates, this is specifically allowed and the compiler will choose one definition for you. That is what is happening in your case and what you call "overriding".
Memory layout is a compile-time concept; it has nothing to do with the linker. The main function thinks TImage is smaller than the CreateImage... functions do, because it was compiled with a different version of TImage.
If the CreateImage... function were defined in the header as inline functions, they would become part of main.cpp's compilation unit, and would thus report the same size characteristics as main reports.
This also has nothing to do with templates and when they get instantiated. You'd observe the same behaviour if TImage was an ordinary class.
EDIT: I just noticed that third line of cout doesn't contain "Created (lib), 10". Assuming it's not a typo, I suspect what's happening is that CreateImageChar is not inlining the call to the constructor, and is thus using main.cpp's version.
Template creates duplicates of classes (ie space) during the compilation itself. So when you are using too much of templates, the smart compilers try to optimize them based on parametrization of templates.
Within your library, you have a TImage that prints "lib" on construction, and contains an array of T. There are two of these, one for int and one for char.
In main, you have a TImage that prints "main" on construction, and does not contain an array of T. There is only the char version in this case; because you never ask for the int version to be created.
When you go to link, the linker choses one of the two TImage<char> constructors as the official one; it happens to chose main's version. This is why your third line prints "main" instead of "lib"; because you are calling that version of the constructor. Generally, you don't care which version of the constructor gets called... they are required to all be the same, but you have violated that requirement.
That's the important part: your code is now broken. Within your library functions, you expect to see that array of char within TImage<char> but the constructor never creates it. Further, imagine if you say new TImage<char> within main, and pass the pointer to a function within your library, where it gets deleted. main allocates one byte of space, the library function tries to release ten. Or if your CreateImageChar method returned the TImage<char> it creates... main will allocate one byte on the stack for the return value, and CreateImageChar will fill it with ten bytes of data. And so on.
I have a task to interface with a dll from a third party company using C++.
The dll package comes with:
the dll itself
a sample Java implementation - consists of a java wrapper(library) generated using the SWIG tool and the the java source file
documentation that states all the public datatypes, enumeration and member functions.
My other colleague is using Java(based on the example in package) to interface with the dll while I'm asked to use C++. The Java example looks straight forward... just import the wrapper and instantiate any class described in the docs..
More info on the dll:
From the docs, it says the dll was programmed using C++
From a hexdump, it shows that it was compiled using VC90 (VS C++ 2008 right?) and something from Dinkumware.
From a depends.exe output, the functions seems to be wrapped under JNI. For example: _Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20
My dilemma:
The dll company is not changing anything in the dll and not providing any other info.
How do i use the member functions in the class from the dll?
I did some simple LoadLibrary() and GetProcAddress and manage to get the address of the public member functions.
But i dunno how to use the functions that has the datatype parameters defined in the dll. For example:
From the docs, the member function is defined as:
void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray
how do i call that function in C++. The std::map and std::vector in my compiler (VS 2005) has different functions listing that the one in the dll. For example, from the depends.exe output:
std::map // KeyValueMap - del, empty, get, has_1key,set
std::vector // StringArray - add, capacity, clear, get, isEMPTY, reserve, set, size
Any advice/strategy on how i should solve this? Is it possible to simply instantiate the class like the Java example?
If you are trying to use VS 2005 to try and interface with a DLL that is built using VS2008, your attempts will be mostly doomed unless you can use a plain C interface. Given your description, this is not the case; The runtime libraries differ between VS2005 and VS2008 so there is little chance that the object layout has stayed the same between compilers. The 'something from Dinkumware' that you're referring to is most likely the C++ standard library as ISTR that Microsoft uses the Dinkumware one.
With your above example you're also missing several important pieces of information - the types you describe (Server::StringArray and Server::KeyValueMap) are standard library containers. OK fine, but standard library containers of what? These containers are templates and unless you know the exact types these templates have been instantiated with, you're a little stuck.
Is this DLL intended to be called from C++ at all? The fact that it export a JNI interface suggests that it might not be in the first place. Does it export any other public symbols apart from those that are of the format _Java_...?
Of course if there is no other way in and you must use C++ instead of Java, you might want to look into embedding a JVM into your C++ app and use that to call through to the C++ dll. It's not what I'd call an elegant solution but it might well work.
I don't quite understand the use of C++ standard library data types here. How can Java code provide a std::map argument? Are the arguments you pass in always just "opaque" values you would get as output from a previous call to the library? That's the only way you're going to be able to make it work from code under a different runtime.
Anyway...
When you make a JNI module, you run javah.exe and it generates a header file with declarations like:
JNIEXPORT void JNICALL Java_Native_HelloWorld(JNIEnv *, jobject);
Do you have any such header file for the module?
These symbols are exported as extern "C" if I recall correctly, so if you can get the correct signatures, you should have no issues with name mangling or incompatible memory allocators, etc..
The "#20" at the end of the method signature means that the function is declared "stdcall" and that 20 bytes are put on the stack when the function is called. All these methods should start with a JNIEnv* and a jobject, these will total 8 bytes I believe, on a 32-bit environment, so that leaves 12 bytes of parameters you will need to know in order to generate a correct function prototype.
Once you figure out what the parameters are, you can generate something like this:
typedef void (__stdcall *X)(JNIEnv *, jobject, jint i, jboolean b);
Then, you can cast the result of GetProcAddress to an X and call it from your C++ code.
X x = (X)GetProcAddress(module, "name");
if (x) x(params...);
Unfortunately, what you have doesn't quite look like what I have seen in the past. I am used to having to deal with Java data types from C/C++ code, but it looks like this module is dealing with C++ data types in Java code, so I don't know how relevant any of my experience is. Hopefully this is some help, at least.
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