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
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.
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):"
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
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?
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.