1

I want to use the cpp functions of an R-package (AlgDesign - https://github.com/jvbraun/AlgDesign/tree/master/src) within my own cpp project.

My usual IDE is Visual Studio 2015. I have found this related post Building R packages (C API) with Visual Studio (and How do I compile a dll with R and RCPP?) So I installed MinGW and CodeBlocks IDE on my Windows 8.1 and retry. I added the "Rdir/include" path to the "Project build options->search directories->compiler" within CodeBlocks.

But I still get "undefined reference _GetRNGstate" which is equivalent to MSVC "unresolved external symbol _GetRNGstate". So i guess the issue is a missing lib like the original questioner already mentioned. But i could not figure out which one either. There is no .lib file in my R-install dir.

Furthermore is not my intend to use Rcpp or to build an own R-package, I just want to access the SEXP FederovOpt(..args) function within my own cpp-project´

Edit: Lets say i want to transfer the AlgDesign src file function by function into an empty project. At some point I'll reach this:

#include "wheeler.h"

#include <string.h>
#include <stdlib.h>
#include <Rinternals.h>
#include <Rdefines.h>
#include <R.h>
#include <Rmath.h>
#include <R_ext/RS.h>
#include <R_ext/Utils.h>

/* Permute **********************************************************
|   Randomly pemutes the n integers in a[] using the Fike
|   algorithm.  See Fike, "A permutation generation method"  The Computer
|   Journal, 18-1, Feb 75, 21-22.
*/

void Permute(
    int     *a,
    int     n
)
{
    int         i,
        j,
        temp;

    GetRNGstate();
    for (i = 1; i < n; i++) {
        j = (int)((double)(1 + i)*unif_rand());
        temp = a[j];
        a[j] = a[i];
        a[i] = temp;
    }
    PutRNGstate();
}

int main(){

return 0;

}

I'll get 3 unresolved externals void GetRNGstate(void) defined in Random.h of R C API void PutRNGstate(void) defined in Random.h of R C API double unif_rand(void) defined in Random.h of R C API

Finally, i found this post: https://www.codeproject.com/Questions/1192515/I-want-to-run-R-script-from-Cplusplus-code

So of course, i am searching for a .lib file. But this file does not exist in Windows, i have to create the .lib file on my own. But i dont know how. I have found this, but it is very old and directories are completly different: https://uploads.cosx.org/2009/12/Integrate-R-into-C.pdf

Could you please help me? A simple "easy peasy use a makefile" or single cmd command wont help me, i cannot understand that. I never worked with makefiles before and i never build a .lib before.

StephanH
  • 463
  • 4
  • 12

1 Answers1

0

I see two possible approaches:

  1. Embed an R interpreter into your application, e.g. using the Rinside package. Then you can call the R function that wraps around FederovOpt.
  2. The FederovOpt function wraps around some normal C functions that do the actual work. It’s main task is to interface these C functions with R. If you are not using R otherwise you could also extract these C functions and use them directly.

Which solution to use? If you need other R functionality, 1. might be easier. Have a look at the examples that come with Rinside. You probably have to stick with mingw, preferably from Rtools. If this is the only R functionality you need, 2. Is probably the way to go. If you make the code independent of R, you can use VS. There are examples where something similar was done, e.g. https://github.com/zhanxw/libMvtnorm. In both cases you have to abide to the GPL.

To make option two more explicit I made a simple test:

  1. Download FederovOpt.c and wheeler.h.
  2. Remove all #includes of R specific headers.
  3. Add #include <math.h> and #defines for TRUE and FALSE.
  4. Remove the R specific functions ProgAlloc, ProgDealloc and FederovOpt
  5. Remove R specific function calls R_CheckUserInterrupt(), GetRNGstate() and PutRNGstate().
  6. Replace unif_rand() with rand() / (RAND_MAX + 1.0).

The resulting file can be compiled with gcc without error or warning. One could even link it without the need for R specific libraries when one adds a main(). In there you would allocate memory, call FederovOptimize and free the memory again.

BTW, the RNG is of course much worse than R's RNG, but might be sufficient for this task. With C++11 you have of course better possibilities available.

Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75
  • Thank you for the answer, but i dont understand them. 1. how should an additional package help ne to use the R C api if i am not able to use the api without the package. I cannot compile my project because there is a missing .lib file 2. I already tried to seperate the FederovOpt function from "rmath.h", "rinternals.h" etc. but it requires to much of these stuff. I need to include the R C api into my project, but there is a missing library. I dont want to install more an more stuff which is not working proper,since up to this point everything failed (installing MinGW, CodeBlocks etc.) – StephanH Aug 29 '18 at 10:07
  • I just want to compile a "#include int main(){}" on Windows thats all for the moment. From that point ill be able to use FederovOpt. I dont think Rcpp and Rinside are packages which are required, since the AlgDesign package requires the original R C api. I only need to know, where the missing .lib file is. So even when i successfully add Rcpp and Rinside i cannot compile the original C api without the missing library. – StephanH Aug 29 '18 at 10:11
  • If there are protypes which doesnt have a definition but the functions are call the corresponding project cannot be compiled regardless of the compiler and OS. No additional packages will help to overcome this problem, i need to find the library first. – StephanH Aug 29 '18 at 10:21
  • @StephanH see the updated answer for an alternative approach. – Ralf Stubner Aug 29 '18 at 11:14
  • Ok, thank you. But i dont understand. I dont want to setup linking myself. I just need to know which library includes the definitions for e.g. GetRNGstate() Even if i want to setup linking manually, I need to know which file includes the definitions of the prototypes. I am not used to makefiles and comand line stuff. I dont know how this should help me to find the missing definitions or library, respectively. – StephanH Aug 29 '18 at 11:46
  • I edited my question, to show you what my current problem is. – StephanH Aug 29 '18 at 12:44
  • @StephanH I don't think it is really difficult to separate `FederovOptimize`, which does the actual work, from the interface function `FederovOpt`. See the updated answer. – Ralf Stubner Aug 29 '18 at 16:59
  • I already tried that but i stopped at point 2. Everythings get a red underline "AS_NUMERIC", "INTEGER_POINT" "PROTECT", "UNPROTECT" "SET_STRING_ELT". etc. etc And simply removing things dont seems to be reasonable – StephanH Aug 29 '18 at 17:05
  • I cannot remove FederovOpt since it is returning "alist" containing my experimental design. I need this function, FederovOptimize only returns the number of iterations, its just a part of FederovOpt – StephanH Aug 29 '18 at 17:11
  • @StephanH The things I have removed are necessary for interfacing a C program with the R interpreter. See [Writing R Extensions](https://cran.r-project.org/doc/manuals/r-release/R-exts.html) for the full details. You want to interface C code with C++. So it makes *perfect* sense to remove these unnecessary parts. Also, *everything* that goes into `alist` is returned by `FederovOptimize`. Most of it via *output arguments*, i.e. pointers where you reserve a chunk of memory and let the called function write its output to. But in the end it is up to you if you want to follow my suggestions. – Ralf Stubner Aug 29 '18 at 17:26
  • You are right. It really compiles and int rows seems to be a list of rows within the candidate list X. I am really excited, mabye i can figure out with FederovOpt.R how to use the function within C++. Thank you a lot – StephanH Aug 29 '18 at 17:56