How can i use Rcpp as a 3rd library for C++? - c++

I can't use Rcpp as a 3rd party library for C++.
My sample code is as follows:
main.cpp
#include <Rcpp.h>
#include <iostream>
using namespace Rcpp;
int main() {
std::cout << 1;
Rcpp::ListMatrix a;
system("pause");
return 0;
}
Then I compile using g++
g++ main.cpp -E -o main.i -I "D:/R-4.1.0/include" -I "D:/R-4.1.0/library/Rcpp/include"
g++ -S main.i -o main.s
g++ -c main.s -o main.o
g++ main.o -L"D:\R-4.1.0\library\Rcpp\libs\x64" -l "Rcpp" -L"D:\R-4.1.0\bin\x64" -l "R" -o main.exe
It successfully spawned main.exe.
But when I run main.exe, the program throws an exception.
It shows that these codes in Rcpp cannot run.
Vector( const Dimension& dims) {
Storage::set__( Rf_allocVector( RTYPE, dims.prod() ) ) ;
init() ;
if( dims.size() > 1 ){
AttributeProxyPolicy<Vector>::attr( "dim" ) = dims;
}
}
Then I found that when the constructors of vector in Rcpp all have functions prefixed with Rf, exceptions are thrown.
why this happen?
I try this,and it it didn't throw exception.
#include <Rcpp.h>
#include <iostream>
using namespace Rcpp;
int main() {
std::cout << 1;
Rcpp::S4 a;
system("pause");
return 0;
}
I think it may have something to do with the function prefixed with Rf.

Related

How to write a static C++ library and link it to an executable using g++ on Windows 10?

main.cpp
#include <iostream>
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
foo.cpp
#include <iostream>
extern "C" {
void foo() {
std::cout << "bar" << std::endl;
}
}
Compile static library:
$ g++ foo.cpp -static
Error:
undefined reference to `WinMain'
But this compiles:
$ g++ foo.cpp -shared -o foo.lib
Now I have a static library named foo.lib (supposedly).
I try to compile an executable that links to it:
$ g++ -L -lfoo main.cpp -o main.exe
And get this error:
'foo' was not declared in this scope
But foo is declared in the static library that I'm linking with. If the link works, I don't think I need to declare it in main.cpp also. So why isn't the link working?
Update.
I added void foo(); to main.cpp so it doesn't complain that foo needs to be declared.
#include <iostream>
void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
So I try to compile again and I get this new error:
undefined reference to `foo()'
Why would I need to define foo in main.cpp? It's already defined in foo.cpp which is the static library.
If I have to define foo in main.cpp that defeats the entire purpose of linking to the library foo.lib.
UPDATES
Removing all the extern "C" { ... } lines doesn't make the "foo is undefined" errors go away.
What follows are the magical incantations you seek:
main.cpp
#include <iostream>
extern void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
}
foo.cpp
#include <iostream>
void foo() {
std::cout << "bar" << std::endl;
}
Console commands:
$ g++ -o foo.obj -c foo.cpp
$ ar rcs foo.lib foo.obj
$ g++ main.cpp foo.lib -o main.exe
These spells conjure up the static lib foo with the executable main statically linked to it.

LLVM opt cannot find function pass

Given the following function pass definition and registration:
// STL
#include <map>
#include <vector>
#include <utility>
// LLVM
#include <llvm/Pass.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/CFG.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/InstIterator.h>
#include <llvm/IR/Constants.h>
// For older versions of llvm you may have to include instead:
// #include "llvm/Support/CFG.h"
// #include <llvm/Support/InstIterator.h>
using namespace llvm;
namespace {
class DefinitionPass : public FunctionPass {
public:
static char ID;
DefinitionPass() : FunctionPass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &au) const {
au.setPreservesAll();
}
virtual bool runOnFunction(Function &F) {
// TODO
errs() << "def-pass\n";
return false;
}
};
class FixingPass : public FunctionPass {
public:
static char ID;
FixingPass() : FunctionPass(ID){}
virtual bool runOnFunction(Function &F){
// TODO
errs() << "fix-pass\n";
return true;
}
};
} // namespace
char DefinitionPass::ID = 0;
char FixingPass::ID = 1;
// Pass registrations
static RegisterPass<DefinitionPass> X("defpass", "Reaching definitions pass");
static RegisterPass<FixingPass> Y("fixpass", "Fixing initialization pass");
I compile this given the following makefile. The compilation is successful:
CXXFLAGS = -rdynamic $(shell llvm-config --cxxflags) -g -O0 -std=c++0x
all: p34.so
%.so: %.o
$(CXX) $(CXXFLAGS) -dylib -shared -fPIC $^ -o $#
clean:
rm -f *.o *~ *.so
Then I create the bitcode file for the file I want to analyse using:
clang -O3 -emit-llvm test1.c -c -o test1.bc
And use opt in the following way:
opt -load p34.so -defpass < test1.bc > /dev/null
But opt is unable to find the function pass "defpass":
opt: Unknown command line argument '-defpass'. Try: 'opt --help'
I'm on OSX and use the homebrew installed LLVM version.
Does anbody have an idea why opt cannot find the pass?
.so Files are for Linux/Unix. On MAC you should be using p34.dylib
Quoting "https://github.com/banach-space/llvm-tutor"
"Finally, run HelloWorld with opt (use libHelloWorld.so on Linux and libHelloWorld.dylib on Mac OS):"

gcc --version-script cannot recognize int64_t

The code examples explain the problem fairly straightforward:
Hash.h
#include <iostream>
#include <cstdint>
using namespace std;
class Hash {
public:
Hash(int64_t sz);
int64_t size;
};
Hash.cpp
#include "Hash.h"
using namespace std;
Hash::Hash(int64_t sz) : size(sz)
{
cout << "Hash int" << endl;
}
main.cpp
#include "Hash.h"
using namespace std;
int main(int argc, char *argv[])
{
Hash HashTable(12);
return 0;
}
And here is the version file, foo.map:
VER_0.1
{
global:
extern "C++" {
"Hash::Hash(int64_t)";
};
local:
*;
};
For the compilation:
$g++ -g -c -Wall -Werror -fpic Hash.cpp -std=c++0x
$g++ -shared -o Hash.so Hash.o -std=c++0x -Wl,--version-script=foo.map
$g++ -g -o prog Hash.so main.cpp -std=c++0x
The error message:
/tmp/ccd60Ulm.o: In function `main':
/remote/ltg_engine1_us03/liangwa/test/004/main.cpp:7: undefined reference to `Hash::Hash(long)'
collect2: error: ld returned 1 exit status
Then if I change all int64_t to int or long, it compiles fine. So anything special with int64_t? I am using g++ 7.3.0

Linking shared libraries with executables

I have a small doubt in the compilation of a c++ code along with a shared library.
So I have two files main.cpp and sample.cpp.
main.cpp
#include <iostream>
using namespace std;
#include "sample.h"
myStruct obj;
void populateData() {
obj.s = "hello world";
}
myStruct giveData() {
cout << "Inside main: " << obj.s << endl;
return obj;
}
int main() {
populateData();
}
sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
#include <string>
struct myStruct {
std::string s;
void populateData();
};
myStruct giveData();
#endif
sample.cpp
#include "sample.h"
#include <iostream>
#include <boost/python.hpp>
using namespace std;
void myStruct :: populateData() {
cout << giveData().s;
}
BOOST_PYTHON_MODULE(boosts) {
using namespace boost::python;
class_<myStruct>("struct")
.add_property("s", &myStruct::s)
.def("populateData", &myStruct::populateData)
;
}
I compile the program using
g++ -c -fPIC sample.cpp
g++ -c -fPIC main.cpp
g++ -shared -Wl,-soname,boosts.so -o boosts.so sample.o main.o -lpython2.7 -lboost_python
g++ -o main main.o
./main
Now, when I run the main, it populates the string inside the obj. But when I run a python script, that imports the boosts.so, the obj.s is empty.
I am guessing it is because the library boosts.so is not properly linked with the executable main.
How do I fix this?

C++ linking object's files (G++)

class.h
#include <iostream>
#include <stdint.h>
using namespace std;
template <typename T>
class CIntegerType {
public:
void Show ( void );
private:
T m_Data;
};
class.cpp
#include "class.h"
template <typename T>
void CIntegerType<T> :: Show ( void ) {
cout << m_Data << endl;
}
main.cpp
#include "class.h"
int main ( void ) {
CIntegerType<uint32_t> UINT32;
UINT32 . Show ();
return 0;
}
This commands return:
g++ -Wall -pedantic -c main.cpp
g++ -Wall -pedantic -c class.cpp
g++ -Wall -pedantic -o class.o main.o
main.o: In function `main':
main.cpp:(.text+0x11): undefined reference to 'CIntegerType< unsigned int>::Show()'
collect2: ld returned 1 exit status
Try putting your template implementation in the header file.
See: Why can templates only be implemented in the header file?
Try g++ -Wall -pedantic -o main.o class.o instead. You are facing the same problem as in this question: g++ linking order dependency when linking c code to c++ code
The linker searches for functions in the order they appear. Since you have a template function, its use in main must be fed to the linker prior to the actual code to instantiate it in class.