Library for managing paths/URLs - c++

Is there any library in C or C++ that helps with managing paths or URLs?
Or maybe functions from standard library from one of these languages
Example:
Imagine following API:
class Path {
public:
Path(std::string &path);
std::string getPath();
void cd(std::string &path);
}
What I need is that this library will handle following cases:
Example 1:
Path *p = new Path("/level_one/level_two/level_three");
p->cd("..");
and now p->getPath() == "/level_one/level_two";,
Example 2:
p->cd("../level_TWO");
and now p->getPath() == "/level_one/level_TWO";,
Example 3:
p->cd("/level_ONE");
and now p->getPath() == "/level_one";.
I hope that these examples made my problem more clear. Basically I need library, that will keep track all change directory commands with respect to syntax of cd on POSIX systems.

Have a look at google-url project, its used inside Chrome and its C++.

The Boost Fileystem library has a path class which supports much of what you're looking for.
Instead of a cd command, it overloads operator=/ for descending directories and has a parent_path() method for ascending.
It's very portable and easy to learn. It is, however, unable to deal (AFAIK) with URL paths.

Related

Load a dynamic shared library (DLL) on Mac in C++ using CFBundleCreate

How do I implement a function to load a dll(aka framework) on Mac OS using C++?
void LoadFramework(const char* frameworkPath)
{
//frameworkPath is the absolute path of the framework
}
Edit:
When I google searched for this problem, I mostly ended up with dlopen solution to load the framework. What I am instead looking for is to use CFBundleCreate to load the framework. It seems to me that there are a bunch of methods needed to be called to construct an URL from const char * path. I found the needed code in pieces, and could not write one comprehensive solution.
It typically is just a few lines of straightforward code to open a framework in Mac, something along the lines of :
bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
CFSTR("/System/Library/Frameworks/<your_framework_name.framework>"),
kCFURLPOSIXPathStyle, true);
bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);
assert(bundle != NULL);
and pretty much everything in that snippet is well documented. I would suggest adding more detail in the question, as to the specifics of what exactly is not working for you.
Why not do this?
using DLL_Namespace;
This should give you access to the DLL.

Project structure in C++ in relation to publicly exposed headers

I am trying to understand project structure in c++, I am finding it difficult to get my head around class structure and header files.
Extract from article 1 (linked at bottom of this post)
By convention, include directory is for header files, but modern practice > suggests that include directory must strictly contain headers that need
to be exposed publicly.
My first question of this process is with regards to a separate class file that is within the include directory.
What is purpose of exposing your headers?
Following on from this, looking at an example of an exposed header file. Linked in the following GH repo: https://github.com/AakashMallik/sample_cmake
How does the Game_Interface class relate back to the Game_Engine?
game_interface.h
#pragma once
#include <game_engine.h>
class GameInterface
{
private:
GameEngine *game;
public:
GameInterface(int length);
void play(int num);
};
I have looked else where for a simple explanation of this process but, all I have found so far is nothing that can be understood in the context of this example.
Fairly new to C++ background in web technologies.
Link to article 1: https://medium.com/heuristics/c-application-development-part-1-project-structure-454b00f9eddc
What is purpose of exposing your headers?
Sometimes you may be developing some functionality or a library. You might want to help some other person or customer or client by sharing the functionality of your code. But you don't want to share the exact working details.
So for instance you wish to share an Image processing functionality which applies beautiful filters to it. But at the same time you don't want them to exactly know how did you implement it. for such scenarios, you can create a header file, say img_filter.h having function declaration -
bool ApplyFilter(const string & image_path);
Now you can implement entire details in img_filter.cpp:
bool ApplyFilter(const string & image_path)
{
....
// Implementation detail
...
}
Next you can prepare a dll of this file which could be used by your client. For reference of working, parameters, usage etc. you can share the img_filter.h.
Relation with Interface:
A well defined interface is generally nice to have so you can change implementation details transparently, which means, that HOW you implement the details don't matter as long as the interface or the function name and parameters are kept intact.

How to specify a remote preprocessor include path like 192.0.2.17://usr/include

Is it possible to specify a C/C++ include path to a remote preprocessor server?
The point here is to have once central location for header files. This makes upgrades, version consistency, and a host of other things much better than people running all willy-nilly including different versions of things.
Minimal, Complete, and Verifiable Example
Typical include. On Linux, would default to /usr/include/ or the like; in Windows VS, to a location specified in the $(IncludePath) variable.
#include <iostream>
int main() {
std::cout << "hello, world" << std::endl;
return 0;
}
Now imagine that we set our include path as follows:
C_INCLUDE_PATH=192.0.2.17://usr/include;/usr/include;
The above would first check the remote server at 192.0.2.17 to see if the iostream library existed. Failing this, /usr/include would be checked.
This is a bit of a stretch to illustrate the point:
#include <192.0.2.17://iostream>
int main() {
std::cout << "hello, world" << std::endl;
}
Thanks, Keith :^)
Since you want version control anyway you could just use git (like thousands of other projects). So each user has a local clone of anything needed.
To answer the original question: No. I'm not aware of any preprocessor supporting such an include scheme.
I'm not aware of any compiler that retrieves include files or libraries remotely, so this is not something you can do directly.
The best you can do is have these dependencies on an NFS share that you can mount and then add that path to your include path.
I wouldn't put references to this in the code like that, and as dbush said, you'd have to enhance the preprocessor.
But there might be cute ways to do this within the Make system. That is, if you're using Make (for instance), you could add steps to the Makefile that force a refresh of data.
However, I would suggest this is WRONG because it's not just the include files that need to be fresh. If an include has changed, the related code has probably also changed, and you would need those changes, too. Your magic #include stuff isn't going to do a thing to make sure people have the right code / libraries that the includes are for.
I'm not sure why proper use of source code repositories don't already handle this for you.

With g++ Is there way for a dynamically linked library to be loaded under a specified namespace without modifying source?

With g++ is there a way to link a library so that all symbols are under a new namespace?
For example, I'd like to use a library in my program which has conflicting symbols with my existing code. Is there a way to encapsulate the linked library under a new name space through the linker, without the need to modify source code?
Edit
Here is some more detail:
I am working on a Qt application, which functions as an "Application Manager" for an embedded device. This application links the Qt module "webkitwidgets", which is a library.
the applications managed by this application manager are built as shared libraries, and when they are launched by this manager program a wrapper programed (Launcher) is forked, the launcher uses QLibrary to load the shared library:
bool ProcessInitImpl::loadLibrary(const QString& libraryPath) {
qTrace() << libraryPath;
QLibrary lib(libraryPath);
lib.setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint);
if (lib.load()) {
qDebug() << libraryPath << " is loaded successfully!";
typedef void (*RegistrationMethod)();
RegistrationMethod registrationMethodInTheSharedLibrary = (RegistrationMethod) lib.resolve("registerMetaTypes");
if (registrationMethodInTheSharedLibrary) {
registrationMethodInTheSharedLibrary();
return true;
}
}
qCritical() << libraryPath << " failed to load!" << lib.errorString();
return false;
}
the problem is that this launcher is suppose to be decoupled from the manager, using IPC to communicate between the launcher instances and the manager. However, the launcher is linked to the manager, which in turn is linked to webkitwidgets. There is an application which contains conflicting symbols within webkitwidgets.
Given all of that above, the only thing that came to mind for me was modifying the launcher wrapper so that it had no dependencies on the manager and thus didn't link webkitwidgets. I just wanted to see if there was another way to address this before going down that path.
With g++ is there a way to link a library so that all symbols are under a new namespace?
Probably not (namespaces are a C++ thing and are implemented by name mangling), and you don't specify what exactly loading a dynamically linked library means to you and you don't tell anything about the actual conflicts you've got. In reality, it is quite complex. Read Levine's Linkers and Loaders and Drepper's How to Write Shared Libraries for details, and also the documentation of binutils ld, ld-linux(8) etc. Read also about dlmopen(3) (which I never used).
For example, I'd like to use a library in my program which has conflicting symbols with my existing code.
Don't touch the library, or the way you are loading it, but touch your program. It would be much simpler (and you could use tools for that, perhaps code your own GCC plugin or use GCC MELT for that). Perhaps it could be as simple as adding a few namespace and or using in your own C++ source code. YMMV.
Practically speaking, how to approach the problem depends a lot on the actual conflicts you are observing and how much you have ...
I do not think you can do that through linker. You can load library dynamically and manually assign function pointers. For linux this could be done by something like this:
namespace wrapper {
int (*foobar)( int ); // replacing int foobar(int) from lib
};
// initialization code
void *handle = dlopen( "libname", flags );
if( !handle ) ...
foobar = reinterpret_cast<declspec(foobar)>( dlsym( handle, "foobar" ) );
// now calling function
int r = wrapper::foobar( 123 );
Is there an existing way to do it? No, unless there's an API I'm unaware of (that's not unthinkable). You'd need to write a custom loader that does name translation.
It shouldn't be too hard on any open-source OS, where you can just take the existing loader's source code and patch it to do the modifications you need.

Managed C++ - Importing different DLLs based on configuration file

I am currently writing an application that will serve a similar purpose for multiple clients, but requires adaptations to how it will handle the data it is feed. In essence it will serve the same purpose, but hand out data totally differently.
So I decided to prodeed like this:
-Make common engine library that will hold the common functionalities of all ways and present the default interface ensuring that the different engines will respond the same way.
-Write a specific engine for each way of functioning....each one compiles into its own .dll.
So my project will end up with a bunch of libraries with some looking like this:
project_engine_base.dll
project_engine_way1.dll
project_engine_way2.dll
Now in the configuration file that we use for the user preferences there will an engine section so that we may decide which engine to use:
[ENGINE]
Way1
So somewhere in the code we will want to do:
If (this->M_ENGINE == "Way1")
//load dll for way1
Else If (this->M_ENGINE == "Way2")
//load dll for way2
Else
//no engines selected...tell user to modify settings and restart application
The question is...How will I import my dll(s) this way? Is it even possible? If not can I get some suggestions on how to achieve a similar way of functioning?
I am aware I could just import all of the dlls right at the start and just choose which engine to use, but the idea was that I didn't want to import too many engines for nothing and waste resources and we didn't want to have to ship all of those dlls to our customers. One customer will use one engine another will use a different one. Some of our customer will use more than one possibly hence the reason why I wanted to externalize this and allow our users to use a configuration file for engine switching.
Any ideas?
EDIT:
Just realized that even though each of my engine would present the same interface if they are loaded dynamically at runtime and not all referenced in the project, my project would not compile. So I don't have a choice but to include them all in my project don't I?
That also means they all have to be shipped to my customers. The settings in the configuration would only dictate with class I would use to initialize my engine member.
OR
I could have each of these engines be compiled to the same name. Only import one dll in my main project and that particular engine would be used all the time. That would render my customers unable to use our application for multiple clients of their own. Unless they were willing to manually switch dlls. Yuck
Any suggestions?
EDIT #2:
At this point seeing my options, I could also juste make one big dll containing the base engine as well as all the child ones and my configuration to let the user chose. Instead of referencing multiple dlls and shipping them all. Just have one huge one and ship/reference that one only. I am not too fond of this either as it means shipping one big dll to all of my customers instead of just one or two small ones that suit there needs. This is still the best solution that I've come up with though.
I am still looking for better suggestions or answers to my original question.
Thanks.
Use separate DLLs for each engine and use LoadLibrary in your main project to load the specific engine based on the configuration.
Have your engine interface in some common header file that all engines will derive from and this interface will be used in your main project aswell.
It might look like this:
// this should be an abstract class
class engine {
public:
virtual void func1() = 0;
virtual void func2() = 0;
...
};
In each different engine implementation export a function from the DLL, something like this:
// might aswell use auto_ptr here
engine* getEngine() { return new EngineImplementationNumberOne(); }
Now in your main project simply load the DLL you're interested in using LoadLibrary and then GetProcAddress the getEngine function.
string dllname;
if (this->M_ENGINE == "Way1")
dllname = "dllname1.dll";
else if (this->M_ENGINE == "Way2")
dllname = "dllname2.dll";
else
throw configuration_error();
HMODULE h = LoadLibraryA(dllname.c_str());
typedef engine* (*TCreateEngine)();
TCreateEngine func = (TCreateEngine)GetProcAddress(h, "getEngine");
engine* e = func();
The name of the exported function will probably get mangled, so you could either use DEF files or extern "C" in your DLLs, also don't forget to check for errors.
The solution I came to is the following:
Engine_Base^ engine_for_app;
Assembly^ SampleAssembly;
Type^ engineType;
if (this->M_ENGINE == "A")
{
SampleAssembly = Assembly::LoadFrom("path\\Engine_A.dll");
engineType = SampleAssembly->GetType("Engine_A");
engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2));
}
else
{
SampleAssembly = Assembly::LoadFrom("path\\Engine_B.dll");
engineType = SampleAssembly->GetType("Engine_B");
engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2, param3, param4));
}
I used the answer from Daniel and the comments that were made on his answer. After some extra research I came across the LoadFrom method.