I succesfully built an Android NDK application that uses the OpenSL library in Android with the help of this tutorial
http://audioprograming.wordpress.com/2012/03/03/android-audio-streaming-with-opensl-es-and-the-ndk/
In opensl_io.h the following is stated:
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
I was wondering whether this has the effect that on my device the library in /system/lib/libOpenSLES.so is loaded.
I thought that the library has to be loaded at some point because in the Android.mk it is stated
LOCAL_LDLIBS := -llog -lOpenSLES
and the ndk doc tells me that this means that /system/lib/libOpenSLES.so and not any other is used for -lOpenSLES
So I wrote an app with superuser rights that has a FileWatcher on that file.
However it seems that the library is never touched, when I use my OpenSL example.
For other libraries such as /system/lib/libstdc++.so, I can see with a FileWatcher that they are loaded.
So my questions is: Why is /system/lib/libOpenSLES.so not used?
It is not enough to add -lOpenSLES and the #include directives to to make your code actually link to libOpenSLES.so. It would be enough if you place a call to one single function from that library, even in such call will never be executed (be careful not to put it in a block that an optimizing compiler will completely discard).
What is the errors you are getting?. I had a problem with calling these libraries when i was creating an audio app. The problem was that in my java wrapper file i was not loading the libraries. The following code should be used to load the libraries into the java class
static{
System.loadLibrary("com_example_packageName");
}
packageName should be your app package name.
Related
I'm trying to write a wrapper for a C++ function I've written, making use of the Point Clouds Library (PCL). This is my first try interfacing R and C++, so I apologise if any solution is too trivial. My goal is to make a few functions available for myself and my colleagues directly in R, on mac and windows. My example function cloudSize is included at the bottom of the text. I will try to be as clear as possible.
I've installed PCL with the vcpkg package manager for winx64 at C:\src\vcpkg\vcpkg.
This is added to my Environmental Variable Path for my user.
I created an empty R-package with Rcpp.package.skeleton():
C:/User/csvi0001/Desktop/GitHub/RPCLpackage/PCLR
PCL is a massive library, but thankfully modular,and so I only #include the headers that are needed to compile the executable: pcl/io/pcd_io.h, pcl/point_types.h, pcl/registration/icp.h.
Now, since I'd like this to work on more than one OS - and therefore compile on install (?) - I should use a dynamic library? I'll presume that the person installing my package already has a compiled copy of pcl. However, I do not know how to find a flag showing that pcl is installed - how do I find these for inclusion in Makevars(?). CMake must find them when testing the C++ function in VSCode after adding an include path. In lieu of this:
I copy the pcl folder installed by vcpkg to ./src . When I tried copying all the .h files, they seemed to lose track of one another as they refer to eachother through which module they are placed in, e.g. <pcl/memory.h> cannot be found if memory.h is placed directly in ./src. However, flattening the structure of the modules means that every single dependency and #include must be manually changed, in some cases there are also files with the same name in different folders. e.g. pcl/kdtree.h and pcl/search/kdtree.h. After this, it must be done again when replacing < > with " " for each header.
Is there any way of telling Rcpp that the library included in /src is structured?
I'm working on Win 10 winx64.
Since I'm making use of the depends RcppEigen and BH; and I must have C++14 or higher (choice: C++17) I add to my DESCRIPTION file:
LinkingTo: Rcpp, RcppEigen, BH
SystemRequirements: C++17
My actual C++ function:
//PCL requires at least C++14
//[[Rcpp::plugins(cpp17)]]
//[[Rcpp::depends(RcppEigen)]]
//[[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <iostream>
#include "pcl/io/pcd_io.h"
#include "pcl/point_types.h"
#include "pcl/registration/icp.h"
//[[Rcpp::export]]
int cloudSize(Rcpp::DataFrame x)
{
pcl::PointCloud<pcl::PointXYZ> sourceCloud;
for(int i=0;i<x.nrows();i++)
{
sourceCloud.push_back(pcl::PointXYZ(x[0][i],x[1][i],x[2][i])); //This way of referring to elements in a Rcpp::DataFrame may be erroneous.
}
int cloudSize = sourceCloud->size();
return (cloudSize);
}
That is a non-trivial question. In the simplest case, use a 'hook' offered by configure and configure.win to pre-build a (static) library you ship in your sources and then link your package to that.
That said, the Writing R Extensions manual and/or the CRAN Repository Policy (both of which are the references here) expressed more of a preference for an external library -- which may not be an option here if PCL is too exotic.
As the topic comes up with Rcpp, I wrote a short paper about it (at arXiv here) which is also included as a vignette in the package. It requires a few pages to cover the common cases but even then it cannot cover all.
Your main source of reference may be CRAN. The are lots of packages in this space. A few of mine use external libraries, I contributed to package nloptr which uses a hybrid approach ("use system library if found, else build") and some like httpuv always build (a small-ish library).
I've created a managed C++ log parser application using C++ vectors and Winforms. I want to add multithreading and Boost seemed like a better option than Winforms BackgroundWorker because I want to be able to execute my existing C++ function with each thread. I installed Boost multiple times following multiple different tutorials (lastly this one: https://levelup.gitconnected.com/the-definite-guide-on-compiling-and-linking-boost-c-libraries-for-visual-studio-projects-c79464d7282d) and I still have the same issue when I try to #include <boost/thread.hpp>
Error LNK1104 cannot open file 'libboost_thread-vc143-mt-x64-1_78.lib'
I don't know why it's looking for this library when I have Boost 1_79 installed not 1_78. My .lib file also has "mt-gd-x64" not just "mt-x64". I've already specified the correct file path to the library in Project->Properties->Linker->General->Additional Library Directories. I've also tried installing Boost via Visual Studio 2022 NuGet Package Manager. The lib file in that folder is also slightly off. "vc120" instead of "vc143". I've even tried changing the .lib file name to match the file name in the linker error exactly but when I do that I get more errors like LNK1104 cannot open file 'libboost_chrono-vc143-mt-x64-1_78.lib'
Do I just need to delete all my Boost files and download version 1_78 and try again? Why is Visual Studio looking for the wrong file name when it compiles? Is my #include statement wrong?
I ended up solving this problem by downloading boost 1_78, building it, and specifying that folder instead or the 1_79 folder. If anyone might know why the program was looking for 1_78 instead of 1_79 feel free to respond Also big thanks to George Gkasdrogkas who wrote the tutorial that worked best for me on how to install Boost. Tutorial is linked in the question :)
I followed all the procedures explained so far about this matter either in this website or published notes by Dirk, Hadley or others. However, I still have problems in building my package due to the issue regarding cpp11 plugin.
I used RcppArmadillo.package.skeleton() function. I put my cpp file in the src directory. The NAMESPACE file looks as it should which contains importFrom(Rcpp, sourceCpp) line. I also edited DESCRIPTION file and in the LinkingTo section, I added RcppEigen and other packages I use. I finally ran the compileAttributes(verbose=TRUE) function in R and everything looked OK. Therefore, I think I have done everything as I should. I have to also mention that when I compile my code in R using sourceCpp(), it works perfect and is compiled with no errors!
To illustrate better what my dependencies are, I put the first block of my code here:
#include <RcppArmadillo.h>
#include <RcppNumerical.h>
#include <RcppArmadilloExtensions/sample.h>
#include <Eigen/LU>
#include <algorithm>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
// [[Rcpp::plugins(cpp11)]]
The problem is when I build my package and I get errors and warnings for the lines I have auto type which relates to cpp11 plugin.
After searching similar posts on this website, I concluded that I have to force my R compiler to use c++11 and there fore I edited my Makvars file located at ~/.R/Makevars and since I use MAC I added this line:
CXX=clang++ -std=c++11 to that file. However, when I do that those 3 errors go away but 50 new errors are generated as all of the Armadillo variable types, such as mat, uvec, etc are not recognized any more. So I don't know how to fix this.
I think basically putting // [[Rcpp::plugins(cpp11)]] should take care of it as the new version of Rcpp supports this plug in and probably that's why when I run sourceCpp in R I get no errors and everything looks fine. But I don't know what happens when building my package. My Rcpp version is 0.12.8 .
Thank you in advance for any sorts of help.
Plugins for both dependencies (ie other headers) and compiler options are for use by sourceCpp().
Packages do this with LinkingTo: and, for the C++11 directive, either src/Makevars or SystemRequirements. See Writing R Extensions which documents this.
I want to convert my cpp code for static library into Android library.
For this, I'm attempting to use NDK.
But I read NDK documentation and it said that only source code is able to be input for building, "Android.mk".
My Questtion is "Is there any way to build static library for Android system with my cpp library?"
Top module of my cpp library is header file and it can be built on Windows system as ".lib".
Thank you!
Your cpp library should be built with NDK toolchain as "libyourname.a" to begin with. You don't need Android.mk for that, even though in many cases deriving a standards-compliant Android.mk is trivial, and makes the developer's life happier in the long run (See, e.g., github).
The next step should be to prepare a JNI wrapper dynamic library (shared object, .so), which can be loaded from your Java app. That "libyourname_jni.so" will probably have its own, separate Android.mk file. Well, Java is not a must: you can use NativeActivity, or maybe some alternative frameworks.
I suggest the following reading to understand the whole process: http://thesoftwarerogue.blogspot.co.il/2010/05/porting-of-libcurl-to-android-os-using.html
I'm trying to build my application with MSVC 2010 instead of GCC. With GCC everything works fine. My app uses boost_system and boost_thread libraries.
I built boost with VC2010 in "system" layout, that means the libraries are named just libboost_system.lib (and not libboost_system_compiler_threading_version_wtf_snafu.lib)
The libs reside in C:\Boost\lib,
the Makefile specifies
LFLAGS = /NOLOGO /INCREMENTAL:NO /SUBSYSTEM:CONSOLE
LIBS = /LIBPATH:C:/Boost/lib libboost_system.lib libboost_thread.lib Ws2_32.lib
when invoking nmake it compiles, but when trying to link it quits with
LINK : fatal error LNK1104: cannot open file 'libboost_date_time-vc100-mt-1_43.lib
I mean seriously, WTF? I told it to link libboost_systen.lib and libboost_thread.lib how come it tries to link libboost_data_time and why does it assume I built the libs in "tagged" layout??
How can I stop MSVC trying to be smart and guess what I might have wanted to link?
Thanks,
Philipp
This is a feature of the Boost libs with compatible compilers for automatic linking.
(Those convoluted library names cover the myriad of threading and linking options that are available on the platform; there are good reasons to use that convention on Windows...)
More information here:
http://www.boost.org/doc/libs/1_33_1/more/getting_started.html#auto-link
I can't find a page for a more recent version, but I believe the BOOST_ALL_NO_LIB and related options are all still valid in 1.43.
Assuming you are auto-linking (i.e. you've defined BOOST_ALL_DYN_LINK or library specific equivalents).
For layout 'system' you have to define the preprocessor macro:
BOOST_AUTO_LINK_NOMANGLE
to link to the correct library names.
For layout 'tagged' you have to define the preprocessor macro:
BOOST_AUTO_LINK_TAGGED
to link to the correct library names.
I don't know if you could do this override for some libraries and keep the default for others. That would be a very cumbersome setup I'd imagine.