Calling methods of the main program from run time loaded Dll - c++

I have a (big and complex) C++ program with its own classes and methods.(obviously)
I would like to load at runtime a dll. From the main program i want to call a function inside the dll passing a class instance , and this function will use the method of this class.
In pseudo code
Main program:
class MyClass{
myattr1();
myattr2();
mymethod1();
mymethod2();
}
void main(){
MyClass* object = &(new MyClass())
handle_of_the_dll = *some function that load the dll*
dllfunc = getfunc(handle_of_the_dll, "interesting_function")
dllfunc(object)
[...etc...]
and the dll
#ifdef __cplusplus
extern C {
#endif
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
#include all the needed headers from main program, where the class is defined
EXPORT void interesting_functionn(MyClass object){
object.mymethod1();
}
#ifdef __cplusplus
}
#endif
Is this valid/doable/right?
EDIT:
i know that this would be a poor design for a general program, but this method is intended to give the users the ability to use their custom dll that can access the api of the main program. Something like Cpython modules

It is valid and doable. Generate a sample DLL in visual C++ and the code will have all the bases covered. Replace the static linking in the client with LoadLibrary and GetProcAdress.
Name mangling could be an issue, DependencyWalker will help you there.
Keep a low profile with emory management. For example, if you use a memory manager on one side but not on the other, your begging for trouble.

I'd say it's possible, but with all due respect, it looks like bad design to me. There is a circular dependency between the main program and the dll: the program calls functions from the dll, and viceversa. In an ideal design, the main program would consume some dll functions, and the dll wouldn't know anything about the main program, or in general, about its clients.
Perhaps you should isolate the functions from the main program that the dll needs to use in a common dll or static lib which both the program and dll use.

As long as the methods are declared virtual and you pass the object by reference or pointer there should be no problems. If however you want to access non-virtual methods of the class you will need to put it's implementation in a separate DLL.

Related

Variables are garbage collected in C++ DLL

I am currently attempting to integrate the AzureStorageCPP into Unreal Engine 4 by using this documentation page. What I am doing is to create a custom C++ DLL wrapper around AzureStorageCPP, and then have Unreal Link this DLL in Unreal Code.
I installed the AzureStorageCPP as DLLs, via vcpkg. On completion, wastorage.dll is one of the important DLLs that needs to be linked.
The C++ DLL wrapper I wrote around AzureStorageCPP is below:
#include "was/storage_account.h"
#include "was/blob.h"
void UploadFileToAzure(char* FileName)
{
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(U("DefaultEndpointsProtocol=https;AccountName=test;AccountKey=test"));
}
As far as I can tell, azure::storage::cloud_storage_account::parse lives in wastorage.dll
The issue is that when this parsing code is executed as a C++ Console, it runs just fine. The ConnectionString is passed correctly down the callstack to wastorage.dll, and the connection string is not garbage.
Here is the view one level down the callstack from the code above.
However, if I put the code into the C++ wrapper DLL I made called AzureStorage.DLL, link it into Unreal, and call from there, with the same call stack the string becomes garbage when it gets passed into wastorage.dll to parse.
I thought this might be related to this issue, but I still don't understand how to fix this, as I don't control the Parse method that is from AzureStorage.
Here is how I created the C++ DLL wrapper header, the source is already shown above:
AzureStorage.h
#pragma once
#define AZURESTORAGEDLL_API _declspec(dllexport)
#ifdef __cplusplus //if C++ is used convert it to C to prevent C++'s name mangling of method names
extern "C"
{
#endif
void AZURESTORAGEDLL_API UploadFileToAzure(char* FileName);
#ifdef __cplusplus
}
#endif

C++ - call Lua functions from Lua C module without custom .lib file

I have an app that uses a modified version of Lua 5.2. Lua is embedded in an exe and as far I can see (with Dependency Walker) there are no export symbols for its Lua functions. I have no sources of this app. I need to write C module for Lua to use with this app.
I successfully require it in the Lua file that this app processes, but as soon as I'm trying to call any lua_* function app crashes with Access violation error.
Is there a way to find addresses/names of embedded Lua functions and call them?
I asked app developers if I'm allowed to do this, they don't seem to care. The only thing is that modification of the app itself is prohibited.
UPD: As far as I can see, I get Access violation because I'm trying to use Lua proxy lib and it fails to pass calls to exe Lua C functions.
If I'm not using Proxy DLL, I get Multiple VMs detected. Any way to solve this?
My Lua C module code:
#if defined(WIN32) || defined(_WIN32)
# define LUA_BUILD_AS_DLL /* for #define LUA_API __declspec(dllimport) */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <lua.h>
#include <lauxlib.h>
#ifdef __cplusplus
}
#endif
#if defined(WIN32) || defined(_WIN32)
# ifdef __cplusplus
# define MY_LUA_API extern "C" __declspec(dllexport)
# else
# define MY_LUA_API __declspec(dllexport)
# endif
#else
# define MY_LUA_API extern "C"
#endif
using namespace std;
static int Lmytest_test(lua_State *L) {
// Check the arguments.
int argn = lua_gettop(L);
if (argn != 1 || !lua_isstring(L, 1)) {
lua_pushstring(L, "Give me one string argument please!");
lua_error(L);
}
lua_pushstring(L, "Hello world!");
return 2;
}
static const struct luaL_Reg lib[] = {
{ "test", Lmytest_test },
{ NULL, NULL }
};
MY_LUA_API int luaopen_mytest(lua_State* L) {
printf("Before newlib\n");
#if LUA_VERSION_NUM >= 502
luaL_newlib(L, lib);
#else
lua_createtable(L, 0, sizeof(lib) / sizeof(lib[0]));
luaL_register(L, NULL, lib);
#endif
printf("After newlib\n");
return 1;
}
For those who ask what is Lua proxy lib:
http://lua-users.org/wiki/LuaProxyDll
http://lua-users.org/wiki/LuaProxyDllTwo
http://lua-users.org/wiki/LuaProxyDllThree
http://lua-users.org/wiki/LuaProxyDllFour
I need to write C module for Lua to use with this app.
Well... you can't.
If their program does not export Lua's DLL interface, and it doesn't load Lua's DLL, then that means it statically linked with Lua. Unless you actually hack the executable, your DLL module will be talking to a Lua implementation that the main executable is not using. That's why you got a runtime crash; two different pieces of code talking to the same memory doesn't work out.
By statically linking to Lua, the developers of the application made it essentially impossible for users to write their own C modules for their uses of Lua without hacking the binary.
Is there a way to find addresses/names of embedded Lua functions and call them?
Not without a decompiler or really good assembly skills. And thanks to link-time optimization, even those may fail you, since some Lua APIs may have been inlined.
You most certainly can write a C dll and if the Lua environment is a properly compatible Lua system, then you should be able to achieve what you are looking to do. There are a number of things you need to check though:
Find out exactly what Lua version is running in the system you use.
This will let you determine what type of library you will need to compile against.
print( _VERSION )
Check other dll modules this Lua environment is using. Use dependency walker or similar. They should be using the luaopen_() type entry point. If this is the case, then your entry point above should be ok.
Check what you are passing to your methods. You cannot pass lightdata (pointers) between the Lua and your dll - mainly because their allocations will be in a different space. You will get access violations from this.
Check for any external libraries that the Lua system may be using. It is common that you will find a lua5.1.dll or similar. You need to be linking with this to ensure the methods you use, will be within the same application process space.
Often problems like this are more likely that the Lua implementation has been modified, and Lua bytecode and interfaces are not consistent, so very difficult to build against.
Hope this helps.
Btw. Use dependency walker to look into exe's and dll's for available methods. Lua uses the stdcall name mangling, so they are always visible.
http://www.dependencywalker.com/

Export :DLL linking using c++

I know how to use explicit linking for a dll that doesn't contain class but how can link a dll contains class, example:
class math{
public:
int sum(int,int);
};
to load it:
typedef int(*func)(int,int);
int main{
HINSTANCE hDLL; // Handle to DLL
hDLL = LoadLibrary("math.dll");
func add=(func)GetProcAddress(hDLL, "sum");
add(4,5);
return 0;
}
if i do this it stop working and exit the program , if i remove the class it works
GetProcAddress can load up exported symbols form the DLL, provided you called it with the correct name.
In your case the function is not exported in the first place. And if it was, it is surely not called "sum" but some gibberish with 20-40 characters.
For using DLLs with C++ code you'll want to drop the GetProcAddress way entirely, and rely only on the implib that maps the names fine.
For that you add __declspec(dllexport) to the class (preferably with dllimport at the client), and add your DLL project as project reference. Alternatively add the .lib that was created along with the DLL to the client project.
C++ compilers use name mangling to uniquely distinguish identifiers in your program. This mangling causes the name to be significantly different than the plain identifiers you use in your program. Because of this using GetProcAddress is typically impractical for accessing code written in C++ that resides in a DLL. Instead I recommend using __declspec(dllexport) and __declspec(dllimport) to provide painless access to the code residing in your DLL.
In your DLL's project you will want to add a preprocessor definition with a name such as "EXPORT_CLASSES" or one unique to the DLL. This will be used by your DLL and program to determine if a particular declaration should be exported by the DLL or imported by the program.
dllstuff.h
#ifdef EXPORT_CLASSES
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif
You will then change the class declaration for math to use this. When the DLL is compiled IMPORT_EXPORT will be equal to __declspec(dllexport) and will instruct the compiler and linker that the definitions for this class should be made publicly available (ie. through the DLL's export table).
mathclass.h
#include "dllstuff.h"
class IMPORT_EXPORT math
{
public:
int sum(int, int);
};
Now all you have to do in your main application is include the mathclass.h any time you want to use the math class. You can now instantiate an instance of math and access it's member functions.
#include "mathclass.h"
int main()
{
math m;
int result = m.sum(1, 2);
}
This of course is just a basic description of the process. There are plenty of articles floating around the web (including SO) with provide much more detailed information.

Implementing an interface that is not yet compilated, .cpp include?

i'm using VS2010, and i am designing a MVC application.
Say i have "Project 1" and "Project 2" in a solution. The need to be compiled in that order, P1 compiles to a DLL, P2 to an Exe file that dynamically uses the DLL. P2 declares a view interface. Both projects have a view class that implements the interface (a class with pure virtual methods).
The problem now is, that i cannot include the header file of the interface in P1, because the linker would say then that he cannot resolve this external symbol. Which is of course right, because it is compiled later in P2.
So what i did is, i added the include folder for P2 to P1 and included the interface.cpp in P1 instead of the header file.
It works, but i don't think this is what i am supposed to do. Or isn't it? The interface is obviously compiled twice, once in each project.
I don't want to move the interface to P1, what would solve the problem. Just assume, i don't want that.
Thanks for input.
edit: code snippet:
Project1:
View1.hpp // nothing special
View1.cpp:
#include ViewInterface.cpp
View1::View1(int x) : ViewInterface(int x)
Project2:
ViewInterface.hpp:
#ifdef EXP
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
class ViewInterface : SomeOtherClass, AnotherClass
{
virtual void DECLDIR show(void) const = 0;
virtual void DECLDIR hide(void) const = 0;
}
ViewInterface.cpp:
ViewInterface::ViewInterface(int x) : SomeOtherClass(int x), AnotherClass(int x)
View2.hpp // nothing special
View2.cpp:
#define EXP
#include ViewInterface.h
View2::View2(int x) : ViewInterface(int x)
In order for the executable to use classes from the DLL, you need to make sure that they're exported properly. When you compile the DLL, you mark the class with __declspec(dllexport), and when you compile the executable, you instead mark the class with __declspec(dllimport). Typically this is done with a macro like so:
// In your DLL's header file
#ifdef COMPILING_MY_DLL
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT __declspec(dllimport)
#endif
class MY_EXPORT MyClass
{
...
};
Then, in only your DLL project, you define the macro COMPILING_MY_DLL.
I don't want to move the interface to P1, what would solve the
problem. Just assume, i don't want that.
Then move it to a third entity.
You have to decide what's more important to you. If you want a clean solution, then either move the interface definition to the DLL (P1), or to something that both the DLL and the EXE can use - let's call it "P0". P0 doesn't even have to be something that's compiled - a simple header file in it's own directory with everything defined inline will do just fine. My preferred choice would be to have P0 be a DLL though.
That is the only clean solution. The following "solutions" are really just hacks that I describe for sake of completeness.
If you really want the "dirty" solution, then do the same, with the only difference that you leave the header file defining the interface in the application-source-folder.
And if you want it ultra-dirty, then include the .cpp file when building the DLL like you suggested. It will also work... it's just really yuck.
Of course you do have to be aware of some things. E.g. the "interface" should not have any static data members, and no function in the "interface" should have function local statics. Because if they do, then those static variables will be instantiated twice - once in the DLL and once in the EXE. Also since all code will be compiled into both projects, you have to re-compile both projects if you want to change anything. (The code being duplicated in the DLL and EXE isn't a problem as long as they were compiled from the same code.)
Those limitations of course also apply if you choose the "P0 = just a header file" solution.
And finally there's the really really bad super-dirty solution: implement the interface in the EXE, dllexport it from the EXE and dllimport it in the DLL (yes, that can be done!). Downside is that you would have to do a special EXE build that only builds the import-library for the EXE (which can be done without having the import library for the DLL). With the import library for the EXE you can then build the DLL, and with the import library for the DLL you can then build the EXE itself.
That way the "interface" could even have static data members, and if you change only the code (i.e. no changes in the header-files) then you would only have to re-compile the EXE.

A variable across the whole application

I have a C++ windows application which is composed of several DLLs.
I want to have some sort of a pool from which I'll get objects, but in a way that this pool
would be available in all the DLLs.
So I put it in a "Common" dll which everbody has access to and defined it in a header file like so:
static Pool globalPool;
I do have access from every dll but this pool is created many many times.
I think it happens in each of my DLLs and in each File which include the header file with the definition.
How can I do it properly?
thanks :)
A static declaration of an object makes the object local to the compilation unit.
By using static you're creating a globalPool object (variable) in every compilation unit where you include the header.
But the way to do what you want is not to just remove the static.
Instead define a function providing access to your pool (e.g. a reference to it), and export that function or set of functions from the pool DLL.
Or better -- much better -- forget the idea. It's a generally bad idea. However, if you really want to do it, and can't see any alternative, then above is how to do it.
And if you do that, perhaps think about thread safety.
And perhaps be aware that dynamic loading of Windows DLLs does not work well with compiler support for thread local variables.
Cheers & hth.,
In the header file you need
extern Pool globalPool;
Then in a .cpp file in the Common dll, you need
Pool globalPool;
The extern declaration will put it in the namespace of including modules, and the linker will resolve it to the object in the common dll.
You'll want a header file that looks something like this:
// Common.h
#pragma once
#ifdef COMMON_BUILD
// When building Common.dll, want to export the definition of Pool
#define COMMON_EXPORT __declspec(dllexport)
#else
// When using Common.dll, want to import the definition of Pool
#define COMMON_EXPORT __declspec(dllimport)
#endif
// Declarations of shared globals
struct COMMON_EXPORT Pool {
static int data1;
static int data2;
};
(For more about the dllimport and dllexport stuff, see http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx and http://msdn.microsoft.com/en-us/library/81h27t8c.aspx)
Then in your DLL's build, you will want a source file like this:
// Common.cpp
#define COMMON_BUILD
#include "Common.h"
int Pool::data1 = 0;
int Pool::data2 = 0;
Then, all the DLLs and EXEs that use it should "#include Common.h" and link with the Common DLL, and then they can use Pool::data1, etc.