Loading shared object dynamically which is in the APK libs folder - android-ndk

hope you can help me here. I managed to create my native activity project and packaged it. In the libs folder I have a shared library that is loaded dynamically (dlopen) within the native activity.
I know that the package libs are copied into: /data/data/packagename/lib
but how can I access it using dlopen? Is that possible? I thought I can access it using just the local folder name, like: ./libMySharedLibrary because they all are in the APK/libs subfolder. Does anyone how to get to the correct foldername or how to get access to those shared libraries?

Dynamic linker already knows about your package private libraries - just pass basename and all should be OK:
dlopen("libawesome.so", RTLD_LAZY);
P.S. To avoid surprises you should ensure that your library name unique and doesn't clash with system ones (these are placed at /system/lib and /vendor/lib, also check lib64 directories on 64-bit devices).

Related

How to prevent new files while accepting the modification of existing ones

I'm not sure if this is a StackOverflow or a SuperUser question:
I'm working on some application, which all have the same directory structure:
Main directory : contains the executable, the configuration, and some necessary DLLs (references)
Modules directory : contains the customer related DLLs, their configurations and their references (also DLLs)
Some other directories.
This morning I had the situation that a DLL was copied to a Modules directory, blocking the execution of the application. It was quite difficult to find this.
I would like to configure my "Modules" directory in such a way that no file can be added, while I can freely re-compile the already present DLL(s)?
I'm working with Windows 10, Enterprise edition.

Rename pdb file with visual studio available tools?

A third party software that we build but typically do not modify in any way has some odd behaviour: Since it is build as a static lib, the PDB file it creates is called vc.pdb and is located in the softwares' intermediate folder. Now it creates about 12 of those pdb files, all in different folders, all with the same name for different libraries and different configurations.
When we integrate this third party software in our code we get the LNK4099 warning because the baked in path for the pdb is obviously not there on all machines. Due to the fact that the third party software generates multiple .lib files in one output directory we cannot place the vc<...>.pdb file along with them.
So I am looking for a way to patch the lib files baked in pdb name to something I have under my control. Does Visual Studio build tools provide a way to do that?
Edit: Let me explain in greater detail what we are doing:
We decided to integrate some third party static lib in our projects. The project itself comes as a source package. One developer or the build server or whoever builds this source package which produces statically linked libs called a.lib and b.lib in various build configurations. With them the default visual studio configuration produces vc110.pdb files, because they are called all the same VS automatically put them into $(IntDir). So the pdb files are all over the place.
Now we commit these third party binaries to our VCS for the given project X.
Whoever now uses the static libs in project X has to link them into the final binary. This is the time where the LNK4099 is generated because the pdb files are not in the VCS and not available on this machine.
But we actually cannot commit all the vc110.pdb files, because this is useless. Since the full qualified path is build into the static libs, no other user will be able to replicate that. During linking the full path to the PDBs cannot be found so it looks for vc110.pdb in the location of the lib file.
Since the third party package decided to put a.lib and b.lib in the same directory we can never properly place the pdb files along with them unless we modify the build of the third party package and either rename the pdb files in the vcxproj or split the generation of libs to be in different directories (also in the vcxproj).
That's the point: I would like to not modify the build files of the third party at any time, I would like to be able to use a plain fresh download of this third party package and build it with some "simple" batch script.
The default results of this package are:
/Bin
/Debug
a.lib
b.lib
/Release
a.lib
b.lib
/Temp
/A
/Debug
vc110.pdb
/Release
vc110.pdb
/B
/Debug
vc110.pdb
/Release
vc110.pdb
What I really want is to patch the generated files after the build.
My "simple" batch (or whatever) script could for instance rename the pdb files to a.pdb and b.pdb, which of course would not be enough because the linker would still look for vc110.pdb as it is the compiled-in name. That is why I am looking for a way (via tools like lib or dumpbin, etc.) where I can patch my generated libs to the new pdb name.
Like that:
$ magic /showPDB a.lib
> D:\some_users_machine\unique_path\package\Temp\A\Debug.vc110.pdb
$ magic /newPDB a.lib d:\path\a.pdb
> New PDB name is d:\path\a.pdb
When the consumer then links my patched a.lib it would not try to look for a.pdb at the path above. It would of course also not be found on most machines but then linker would also look for a a.pdb in the location where a.lib is located and that's were I could place it now for all.
Edit 2: For the close due to opinion base: I am looking for a technical way to modify a static lib's baked in pdb location
Take a look at the linker option /PDBALTPATH. This allows you to specify a different PDB path that will be embedded into your binary.
/PDBALTPATH:pdb_file_name
MSDN Article: /PDBALTPATH (Use Alternate PDB Path)

How to handle building files outside of directory

I have a build set up and I'm struggling on how to handle one aspect.
I have successfully setup a variantdir for my project folder src build output, however I have
source that resides outside the project folder that needs to be build and included.
I am able to add the files I need into the build, however the object files are put into the external directory where the library souce files are.
Is there a standard way to solve this. I would like to avoid adding any scons files to the external directory as it is a standard intall of a tool.
What I attempted was to Mkdir() a temporary folder, Copy() the files, and build the files. This seems to work, but only the first time as the file permissions are set to readonly. Also, the only way to get it to work seemed to be to use the Execute() command which caused the action to happen at every build.
Have a look at the Repository() method (see http://scons.org/doc/production/HTML/scons-user.html#chap-repositories in the SCons UserGuide). It lets you sort of "mount" a folder to the top-level of your source tree. Then you can refer to them locally, and specifying "duplicate=1" for your variant dir should keep your remote folder clean from built files.
Hope this helps...
I was able to get the functionality I was looking for by building the objects in the external directory and then using the Move() Factory to move the object files.
If Anyone can point out a more 'scons'sy way of doing it please let me know.

Why is it not recommended to keep the shared libraries in the Executable location

I'm Fairly new to Linux , And Software Development I was suggested that the shared library should be placed separately from the executable location in Linux , But in Windows I could see all the Files including the dll's and the exe are available in the same folder .What kind of problem's it might cause in linux if the exe and the shared library are in the same folder
When executable and library in same folder you can't say library is shared, right? And you'll probably have dozens of same libraries in system - what a waste of space. In Windows there's no organized way of storing libraries in system line /usr/bin or /lib/bin. It's not ok to put them in system32, and there's no other directories in PATH - no choice to make.

How can we protect ourselves from other third parties installing DLLs with the same names as some of ours into C:\WINDOWS?

Our product includes several DLLs built from open source into files with default names as delivered by the open source developers. We're careful to install the files in our own directories and we carefully manage the search path (only for our processes) to keep the loader happy.
Another developer -- a towering intellect -- decided it would be easier to install their own build of some of the same open source into C:\WINDOWS under the same default DLL filenames. Consequently, when we launch a process which depends on these open source DLLs, the system searches C:\WINDOWS before our directories and finds the DLLs installed by the other developer. And they are, of course, incompatible.
Ideas which have occurred to me so far:
rename all our DLLs to avoid the default names, which would only make
it less likely we would encounter collisions
load all our DLLs by full path so the loader captures their names into
RAM and doesn't search anywhere else the next time they are requested
For various reasons, neither of these options is palatable at the moment.
What else can we do to defend ourselves against the towering intellects of the world?
You've got only two options: deploy the DLL in the same directory as the EXE (that's where Windows looks first) or using manifests and deploy the DLL to the Windows side-by-side cache. I don't think the latter option is common in the Open Source world but it is the only real fix if you want to share DLLs between different apps.
To add to the already excellent answers, you have a couple more choices:
The preferred solution(s) to this problem, supported since Windows XP, is to turn your dll's into a win32 assembly (They don't have to be .NET but the documentation on creating win32 assemblies with strong names is appallingly light so its easy to get confused and think this is a .NET only technology).
An assembly is noting more complicated than a folder (With the name of the assembly) containing the dlls and a .manifest (With the name of the assembly) that contains an assemblyIdentiy element, and a number of file nodes for each dll in the assembly.
Assembly based searching works even when dlls are statically linked!
The easiest option is to create unversioned assemblies and store them in the same folder as your .exe files (Assuming all your exe's are in a single folder).
If the exe's are in different folders, then there are two ways to access shared assemblies:
You can store your assemblies in a private alternate location if you expect your application to be used on Windows 7 and higher. Create a app.exe.config file for each of your exe's, and point a probing privatePath element to a common folder where you are storing the assemblies.
If you are ok with requiring administrative access to perform installs, (via MSI's) then you can deal with the appallingly bad documentation (well, absent documentation) that deals with giving your assemblies a strong name, and then store the assembly in WinSxS.
If you can't, or do not want to bundle your dlls as assemblies then this page covers dll search order
Using functions like SetDllDirectory are only going to help for dlls loaded dynamically at runtime (via LoadLibrary).
Dll search order used to be:
Directory containing the process exe
Current directory
various windows folders
PATH
Which you could have used to your advantage - launch each exe, setting the "current" directory to the folder containing the OSS dlls.
With the advent of SafeDllSearchMode the search order now is:
Directory containing the process exe
various windows folders
Current directory
PATH
Meaning theres now less control than ever :( - It goes even faster to the "untrusted" c:\windows & System32 folders.
Again, if the initial dll is being loaded via LoadLibrary, and its the dependent dll's that are the problem, LoadLibraryEx with the LOAD_WITH_ALTERED_SEARCH_PATH flag will cause the following search order (Assuming you pass a full path to LoadLibraryEx) :-
Directory part of the Dll path passed to LoadLibraryEx
various windows folders
Current directory
PATH
The directory from which the application loaded is normally the first directory searched when you load a DLL. You can, however, use SetDllDirectory to get the "alternate search order". In this case, the directory you specify to SetDllDirectory gets searched first.
There is also a SafeDllSearchMode that affects this to a degree. Turning it on excludes the current directory from the search.
Maybe just compile them to a static library?
Why not?
Also, the current directory, where the exe is activated from is searched before c:\windows.

Resources