How to connect a .lib to a DLL in R?

I want to build a DLL with a .lib in Windows.

This is a little complicate for me.

I use a file Makevars and some options like PKG_CPPFLAGS and PKG_LIBS.

File Makevars

PKG_CPPFLAGS += -I. -I../../../../StaticLibrary/MathFuncsLib

PKG_LIBS = -L../../../../StaticLibrary/x64/Debug -lMathFuncsLib1

File in my lib

MathFuncsLib.h

#ifndef Math
#define Math

namespace MathFuncs
{
    class MyMathFuncs
    {
    public:
        // Returns a + b
        static double Add(double a, double b);

        // Returns a - b
        static double Subtract(double a, double b);

        // Returns a * b
        static double Multiply(double a, double b);

        // Returns a / b
        static double Divide(double a, double b);
    };

    int foo3();

    inline int foo2(){
    return 3363;
    };

} 

inline int foo1(){
return 951;
};

int foo4();

#endif //Math

MathFuncsLib.cpp

#include "MathFuncsLib.h"

#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    double MyMathFuncs::Add(double a, double b)
    {
        return a+b;
    }

    double MyMathFuncs::Subtract(double a, double b)
    {
        return a - b;
    }

    double MyMathFuncs::Multiply(double a, double b)
    {
        return a * b;
    }

    double MyMathFuncs::Divide(double a, double b)
    {
        return a / b;
    }

    int foo3(){

    return 205;
    };
}
int foo5(){
return 178;
};
int foo4(){

return foo5();

};

File in my DLL

X_main.cpp

#include "MathFuncsLib.h"
#include <R.h>
using namespace MathFuncs;
extern "C" {

int TestLibStatic() {

 int v=foo1();

 std::cout<<"TestFonction "<<v<<std::endl;
 return v;
}

int TestLibStaticNameSpace() {

    int v1=foo1();
        std::cout<<"TestFonction NameSpace v1 : "<<v1<<std::endl;

    int v2=MathFuncs::foo2();
        std::cout<<"TestFonction NameSpace v2 : "<<v2<<std::endl;

    int v3=MathFuncs::foo3();
        std::cout<<"TestFonction NameSpace v3 : "<<v3<<std::endl;

    int v4=foo4();
        std::cout<<"TestFonction NameSpace v4 : "<<v4<<std::endl;

 return v1;
}

}

Code Return by command

R CMD SHLIB X.cc X_main.cc

return 
g++ -m64 -I"C:/PROGRA~1/R/R-32~1.0/include" -DNDEBUG -I. -I../../../TutoC++/StaticLibrary/MathFuncsL
ib    -I"d:/RCompile/r-compiling/local/local320/include"     -O2 -Wall  -mtune=core2 -c X.cpp -o X.o

g++ -m64 -I"C:/PROGRA~1/R/R-32~1.0/include" -DNDEBUG -I. -I../../../TutoC++/StaticLibrary/MathFuncsL
ib    -I"d:/RCompile/r-compiling/local/local320/include"     -O2 -Wall  -mtune=core2 -c X_main.cpp -
o X_main.o
g++ -m64 -shared -s -static-libgcc -o X.dll tmp.def X.o X_main.o -L../../../TutoC++/StaticLibrary/x6
4/Debug -lMathFuncsLib1 -Ld:/RCompile/r-compiling/local/local320/lib/x64 -Ld:/RCompile/r-compiling/l
ocal/local320/lib -LC:/PROGRA~1/R/R-32~1.0/bin/x64 -lR
**X_main.o:X_main.cpp:(.text+0x8c3): undefined reference to `MathFuncs::foo3()'
X_main.o:X_main.cpp:(.text+0x92d): undefined reference to `foo4()**'
collect2: ld returned 1 exit status

I don’t know why the compiler don’t find the .lib (I compile it with Visual) or .o (I compile it with g++, with the command ‘g++ -m64 -c MyFile -o MathFunsclib.o) in the folder (Makevars):

StaticLibrary/x64/Debug

I think the compiler found foo1 and foo2 because they are defined in MathFuncsLib.h, and this file is included in X_main.cpp.

The compiler found the file in the folder (Makevars): ../…/../StaticLibrary/MathFuncsLib

New command :

R CMD SHLIB X.cc X_main.cc MathFuncsLib1.lib

I put the file “MathFuncsLib1.lib” in the same folder than X_main.cc.

result :

g++ -m64 -shared -s -static-libgcc -o X.dll tmp.def X.o X_main.o MathFuncsLib1.ib -Ld:/RCompile/r-co
mpiling/local/local320/lib/x64 -Ld:/RCompile/r-compiling/local/local320/lib -LC:/PROGRA~1/R/R-32~1.0
/bin/x64 -lR
g++.exe: error: MathFuncsLib1.ib: No such file or directory

D:_testfiles_RCppMultiHeritage_visual_cpp>R CMD SHLIB X.cc X_main.cc MathFuncsLib1.lib
g++ -m64 -shared -s -static-libgcc -o X.dll tmp.def X.o X_main.o MathFuncsLib1.lib -Ld:/RCompile/r-c
ompiling/local/local320/lib/x64 -Ld:/RCompile/r-compiling/local/local320/lib -LC:/PROGRA~1/R/R-32~1.
0/bin/x64 -lR
**X_main.o:X_main.cpp:(.text+0x8c3): undefined reference to `MathFuncs::foo3()'
X_main.o:X_main.cpp:(.text+0x92d): undefined reference to `foo4()'**
collect2: ld returned 1 exit status

I think we cannot link to a .lib. Would I be right ?

New command :

R CMD SHLIB X.cc X_main.cc MathFuncsLib1.o

result :

g++ -m64 -shared -s -static-libgcc -o X.dll tmp.def X.o X_main.o MathFuncsLib1.o -L../../../TutoC++/
StaticLibrary/x64/Debug -lMathFuncsLib1 -Ld:/RCompile/r-compiling/local/local320/lib/x64 -Ld:/RCompi
le/r-compiling/local/local320/lib -LC:/PROGRA~1/R/R-32~1.0/bin/x64 -lR

result of : r -f “script.R”

.C("TestLibStaticNameSpace")
TestFonction NameSpace v1 : 951
TestFonction NameSpace v2 : 3363
TestFonction NameSpace v3 : 205
TestFonction NameSpace v4 : 178
list()
q()

Finally, I have the result, but I don’t want to make this for some reason :
I have a big project with maybe 25 .lib (Visual) that are use to make a .exe.

I wanted to make a DLL which use functions from the 25 lib, they are in several folder.

My final questions :
Must I recompile all my files ? to have .o and not .lib ? In the tutorial of R, I read I can use .lib and .dll in R.

Why the compiler don’t find my .lib or .o in the folder indicated in my Makevars ?

I tried to be clear, but I am confused in this new world (R !!).

Thanks you in advance for any help.


Source: dll

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.