I'm writing my functions in C++ to use them in R. Since I don't want to include all the functions inside the same file, I want to call them. I'll give you a simple example of the three files I'm using:
function.h:
#ifndef FUNCTION_H
#define FUNCTION_H
#include <RcppArmadillo.h>
arma::vec quadraticsum(arma::vec x);
#endif
function.cpp:
#include <RcppArmadillo.h>
#include <function.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
using namespace std;
// [[Rcpp::export]]
arma::vec quadraticsum(arma::vec x){
arma::vec results = sum(pow(x,2));
return results;
}
main.cpp:
#include <RcppArmadillo.h>
#include <function.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
using namespace std;
// [[Rcpp::export]]
arma::vec sum2(arma::vec x){
arma::vec results = quadraticsum(x)+2;
return results;
}
I'm working with Rstudio and when I write the code in the main.cpp file it recognizes the function quadraticsum, and so everything seems to be fine. However, when I compile using the command sourceCpp("~/main.cpp"), I got this error:
Error in dyn.load("/private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so") :
unable to load shared object '/private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so':
dlopen(/private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so, 6): Symbol not found: __Z12quadraticsumN4arma3ColIdEE
Referenced from: /private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so
Expected in: flat namespace
in /private/var/folders/46/1tz_54_n3glfmgftvqsspwrr0000gn/T/Rtmpdnk9hf/sourceCpp-x86_64-apple-darwin13.4.0-0.12.12/sourcecpp_237a88636e6/sourceCpp_2.so
Have you seen this problem before? I'm using macOS 10.12.5. Thank you all.
sourceCpp only allows a single source file.
If you want to use multiple source files, you will need to build a full package.
The error appears because the second source file has not been compiled or linked into the shared library. As a result, no function implementation exists.
You could also make the implementations static or inline and then place them in a header, of you want to avoid a full package. if
I discovered that writing #include "function.h" instead of #include <function.h> it compiles correctly. I just changed it. Thank you all.
Related
I'm learning C++ with plans to implement it almost entirely in conjunction with R. I get a little tired of appending the namespace "std" to tons of code though. Is there a way to use namespace std for most of the code and switch the namespace to Rcpp just for the compile and sourcing?
Below is a C++ "Hello World" function with namespace Rcpp. This is a trivial example, but lays out the problem. "string" is not a class in Rcpp, so I have to append std:: to it. Again, I know this is a trivial example, but I just want to know if it is possible.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
std::string hello(std::string x) {
return x;
}
/*** R
hello("Hello World")
*/
Output works as expected, but I'd love if I could make the code look something like this:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
using namespace std;
string hello(string x) {
return x;
}
using namespace Rcpp;
/*** R
hello("Hello World")
*/
This way, as the bulk of the code expands, I don't have to append std to everything.
tl;dr: Can I somehow make this code work in C++14 (GCC 6.3)?
int main(){
#include<vector>
std::vector<int> v{1,2,3};
return 0;
}
But code below works just fine!
#include <iostream>
using namespace std;
int main() {
#include<cstdio>
using namespace __gnu_cxx;
printf("Hello world\n.");
return 0;
}
Using C++14 (gcc-6.3) code doesn't compile with error message being
error: 'namespace' definition is not allowed here
namespace std
^~~~~~~~~
Why I want to do this?
I don't have access outside of the function where I am allowed to code. I can't #include in global area.
UPD: Changing to cstdlib also works problem is not exclusion by header guard (according to me) but namespace problem. Because C++ header files have namespace std, while c header files doesn't. I wanted to ask whether there is some tweak for namespace issue?
Can I somehow make this code work
No. Standard headers (and most library headers in general) must be included in the global namespace scope.
But code below works just fine!
But it's not guaranteed to work. It just happened to work, probably because <iostream> had already included <cstdio> and so your own inclusion was removed by header guards.
When compiling my .cpp file with Rcpp in R, this error message comes :
undefined reference to `boost::system::generic_category()'
But when I remove the // [[Rcpp::plugins(cpp11)]] line, there isn't any error anymore. Why?
Here is my minimal reproducible example.
// include Rcpp, it takes care of most other headers you need
#include <Rcpp.h>
#include <boost/array.hpp>
// include Boost's odeint
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp>
#include <boost/filesystem/fstream.hpp>
#include <functional>
// tell R you need Boost
// [[Rcpp::depends(BH)]]
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;
using namespace std;
using namespace boost::numeric::odeint;
typedef boost::array< double ,130 > state_type;
// [[Rcpp::export]]
void my_fun22(Rcpp::NumericVector &x, const double t,const Rcpp::NumericVector theta){
Function f("mod_cpp");
x=f(_["t"]=t,_["x"]=x,_["p1"]=theta);
}
Yet another elementary issue: Boost System (generally) requires linking which is a whole different ball game than just pointing to Boost headers via the BH package. And the very standard error message undefined reference comes from the linker / failed attempts to locate a symbol.
We discuss the use of linking to Boost libraries in some posts on the Rcpp Gallery, but the short of it is that there is no portable way to provide linking to Boost libraries across the OSs used by R.
I want to disable bound checks when accessing to matrix elements in RcppArmadillo.
The documentations of Armadillo says
Armadillo can be configured via editing the file
include/armadillo_bits/config.hpp. Specific functionality can be
enabled or disabled by uncommenting or commenting out a particular
#define, listed below.
But in the context of an R package, how can I activate this directive?
I have tried to create a config.h file with
#ifndef CONFIG_LOADED
#define CONFIG_LOADED
#define ARMA_NO_DEBUG
#endif
and then including it in every .cpp file of my /src folder, but I'm not sure whether it works properly or whether there is some other way other than adding a #include "config.h"in each .cpp file.
Currently I have one .cpp (the one that contains the main algorithm) that start with:
#include "configs.h"
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
SEXP sample_gibbs_cpp(const arma::vec& v_n, const arma::mat& W,
arma::vec h_n, double alpha = 1, double beta = 1, int iter=100,
double burnin = 0.5){
... code ...
}
And then others that are just
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
... code ...
My DESCRIPTION file:
Package: mypackage
Title: What the Package Does (one line, title case)
Version: 0.0.0.9000
Authors#R: person("First", "Last", email = "first.last#example.com", role = c("aut", "cre"))
Description: What the package does (one paragraph).
Depends:
R (>= 3.2.3)
License: What license is it under?
Encoding: UTF-8
LazyData: true
RoxygenNote: 5.0.1
Imports:
ggplot2,
dplyr,
tidyr,
rstan
LinkingTo: Rcpp, RcppArmadillo, RcppEigen
SystemRequirements: C++11
And I compile my package with:
devtools::load_all()
Order matters here. This #define statement must be included before the inclusion of #include<RcppArmadillo.h>
An example:
custom_config.h
#ifndef CONFIG_LOADED
#define CONFIG_LOADED
#define ARMA_NO_DEBUG
#endif
example_compiled_file.cpp
#include "custom_config.h"
#include <RcppArmadillo.h>
// [[Rcpp::export]]
void test_pkg(const arma::vec& x) {
// Should not trigger error bound checking with debug flag on.
double my_val_protected = x(0);
// Never triggers error bound checking
double my_val = x.at(0);
}
Note: As this is a package, the use of // [[Rcpp::depends(RcppArmadillo)]] is not required. Instead, you must specify RcppArmadillo and Rcpp in the LinkingTo: field of the DESCRIPTION file as well as including Rcpp in the Imports: field. You will have to minimally import from Rcpp a function (preferably: evalCpp).
e.g. DESCRIPTION must have:
Imports: Rcpp (>= 0.12.15)
LinkingTo: Rcpp, RcppArmadillo
I am reading Accelerated C++ Chapter 4: Organizing Programs and Data. I came across the following piece of code, which is saved to a file called median.cpp:
// median.cpp file contents
#include <algorithm>
#include <stdexcept>
#include <vector>
using std::domain_error;
using std::sort;
using std::vector;
// Compute the median of a vector<double>
double median(vector<double> vec)
{
// Code for what the median function does goes here
}
and then, later on on page 67., the authors discuss an include guard like below, which is saved to a file called median.h.
#ifndef GUARD_median_h
#define GUARD_median_h
// median.h - final version
#include<vector>
double median(std::vector<double>);
//
#endif
Are we supposed to "include" the median.h into median.cpp before compiling, like below?
// median.cpp file contents
#include "median.h"
#include <algorithm>
#include <stdexcept>
#include <vector>
using std::domain_error;
using std::sort;
using std::vector;
// Compute the median of a vector<double>
double median(vector<double> vec)
{
// Code for what the median function does goes here
}
I am asking this because, in section 4.3 where the authors discuss this topic, they have failed to mention how someone is supposed to make use of median.cpp and median.h for compilation.