Suppose I’m building an R package with C files that call C code from other R packages through R_GetCCallable, e.g.
void R_init_thispackage(DllInfo *info) {
…
zoo_lag = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("zoo","zoo_lag");
}
new_cfile.c
SEXP new_func (SEXP arg1, SEXP arg2, SEXP arg3)
{
SEXP temp = zoo_lag(arg1, arg2, arg3);
...
}
And I want to call these C files (from the package being built) in C++ through Rcpp:
When Rcpp generates the file src/RcppExports.cpp, it automatically adds there the function for package initialization (something like R_init_thispackage). Since I need to add an extra line inside the function for the import from another package, I’m wondering if there is some way to tell Rcpp to include that import, e.g. through some keyword, so that it would not need to be added manually after each re-generation.
Related
Let's assume we have a simple module called _sample built with pybind11:
/* py_bindings.cpp */
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(_sample, m) {
m.def("add", [](int a, int b) { return a + b; });
m.def("add", [](const std::string& lhs, const std::string& rhs) { return lhs + rhs; });
}
This produces a dynamic module file _sample.pyd (Windows) or _sample.so (Linux), which we can then import in the actual module sample:
## sample\__init__.py ##
from ._sample import *
So that we can write:
## script.py ##
import sample as s
print(s.add(4, 2)) # 6
print(s.add('AB', 'C')) # ABC
The above code works fine, but the IDE does not know which functions are included in _sample until the code is actually run. And as a result, there are no function suggestions at all (and no function signature suggestions either).
As I would like to help the users of my library, my question is: how do I include function suggestions (or "function hints") in my module?
I've tried including the below code in sample\__init__.py as I thought the ... might work as a "hint". But unfortunately, this overrides the original add function from _sample.
def add(arg0: int, arg1: int) -> int:
...
Are there ways to hint the function signatures to a Python IDE?
Of course, I want to extend this to classes, class functions & module attributes too. I just picked functions as a starting point.
I think what you're looking for is a stub or interface (pyi) file. The IDE can understand the signature of functions and classes from this file.
If you're using pybind11, check out pybind11-stubgen for automatic generation of a stub file.
When creating an R extension in C or C++, objects created in the compiled code need to be manually protected and unprotected from the garbage collector - e.g.:
SEXP some_func(SEXP inp)
{
SEXP some_vec = PROTECT(Rf_allocVector(REALSXP, 100));
// do something with 'some_vec' ...
UNPROTECT(1);
return some_vec;
}
Rcpp OTOH offers convenient classes which automatically handle the PROTECT and UNPROTECT calls, so one can safely do something like:
Rcpp::NumericVector some_func(SEXP inp)
{
Rcpp::NumericVector some_vec(100);
// do something with 'some_vec' ...
return some_vec;
}
Now, if I were to cast the Rcpp objects to generic SEXP, are they still auto protected? Example:
SEXP some_func(SEXP inp)
{
SEXP some_vec = Rcpp::NumericVector(100);
// do something with 'some_vec' ...
return some_vec;
}
Since some_vec was allocated as a specialized NumericVector but then casted to SEXP, does it still undergo automatic PROTECT/UNPROTECT, or do I need to do it manually?
And what about casting the other way around? E.g. is this safe?
Rcpp::NumericVector some_func(SEXP inp)
{
Rcpp::NumericVector some_vec = Rf_allocVector(REALSXP, 100);
// do something with 'some_vec' ...
return some_vec;
}
Yes as the only interface that there is from R uses SEXP .Call(SEXP ...). So every Rcpp object automatically gets transformed (a lot with implicit conversion but also via Rcpp::wrap(...)) and the protection is part of that.
You can easily verify that by for once creating a SEXP manually without the protection layer and R will tell you in R CMD check and/or crash.
From that you can conclude that Rcpp objects are correctly protected as this does not happen to them.
I am writing an R package in which one of the functions takes Rcpp::XPtr as an input (as a SEXP). However, the creation of XPtr from Rcpp::Function is something I want to do inside the package (i.e., the user should be able to input Function).
e.g, my package takes input generated as follows, which requires the user to write an additional function (here putFunPtrInXPtr()) and run the function in R to generate the XPtr (here my_ptr).
#include <Rcpp.h>
using namespace Rcpp;
typedef NumericVector (*funcPtr) (NumericVector y);
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
return x * 2;
}
// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
XPtr<funcPtr> testptr(new funcPtr(×Two), false);
return testptr;
}
/*** R
my_xptr <- putFunPtrInXPtr()
*/
How can I write something in which the user provides Function user_fun and I create the XPtr?
I tried
XPtr<funcPtr> package_fun(Function user_fun_input){
XPtr<funcPtr> testptr(new funcPtr(&user_fun_input), false);
}
user_fun_input is the parameter name inside the package function, but I am getting the following error
cannot initialize a new value of type 'funcPtr' (aka 'Vector<14> (*) (Vector<14>') with an rvalue of type 'Rcpp::Function *' (aka 'Function_Impl<PreserveStorage> *')
Also, there is an R step involved in creating the pointer, I am not sure how to implement that in the package (my .cpp file).
I think the creation of XPtr from Function could be confusing to the user, so better to just take Function as input and create the pointer to it, inside the package. I do use the XPtr in my package to gain speed.
Suggestions are most appreciated!
Is it possible to call a JNI C function inside another JNI C function? (directly or indirectly), or, a JNI function inside a normal C function?
For example:
int inverse_transform(double real[], double imag[], size_t n) {
return Java_com_example_ffttest_FFTActivity_transform(imag, real, n);
}
and inverse_transform() is later called inside another method.
JNIEXPORT jint JNICALL Java_com_example_ffttest_FFTActivity_convolve(...)
{
....
inverse_transform();
}
Does this work? I tried but it gives me errors about parameters and I don't know how to use *env and obj.
Certainly it's possible. Those are just functions with funny names as far as C is concerned.
One word of caution though - if the JNI function uses its JNIEnv parameter, you need to pass a valid one from a non-JNI function.
At the end JNI methods are normal c++ methods so offcourse you can do it .
I came across a problem recently.
I have three files, A.h, B.cpp, C.cpp:
A.h
#ifndef __A_H__
#define __A_H__
int M()
{
return 1;
}
#endif // __A_H__
B.cpp
#include "A.h"
C.cpp
#include "A.h"
As I comile the three files by MSVC, there is a error:
C.obj : error LNK2005: "int __cdecl M(void)" (?M##YAHXZ) already defined in B.obj
It is easy understanding, as we know, B.obj has a symbol named "M", also C.obj has a "M".
Here the error comes.
However, if I change M method to a class which contain a method M like this below:
A.h
#ifndef __A_H__
#define __A_H__
class CA
{
public:
int M()
{
return 1;
}
};
#endif // __A_H__
there is no more errors!! Could somebody tell me what is happening?
If B.cpp and C.cpp include A.h, then both are compiled with your definition of M, so both object files will contain code for M. When the linker gathers all the functions, he sees that M is defined in two object files and does not know which one to use. Thus the linker raises an LNK2005.
If you put your function M into a class declaration, then the compiler marks/handles M as an inline function. This information is written into the object file. The linker sees that both object files contain a definition for an inline version of CA::M, so he assumes that both are equal and picks up randomly one of the two definitions.
If you had written
class CA {
public:
int M();
};
int CA::M()
{
return 1;
}
this would have caused the same problems (LNK2005) as your initial version, because then CA::M would not have been inline any more.
So as you might guess by now, there are two solutions for you. If you want M to be inlined, then change your code to
__inline int M()
{
return 1;
}
If you don't care about inlining, then please do it the standard way and put the function declaration into the header file:
extern int M();
And put the function definition into a cpp file (for A.h this would ideally be A.cpp):
int M()
{
return 1;
}
Please note that the extern is not really necessary in the header file.
Another user suggested that you write
static int M()
{
return 1;
}
I'd not recommend this. This would mean that the compiler puts M into both of your object files and marks M as being a function that is only visible in each object file itself. If the linker sees that a function in B.cpp calls M, it finds M in B.obj and in C.obj. Both have M marked as static, so the linker ignores M in C.obj and picks the M from B.obj. Vice versa if a function in C.cpp calls M, the linker picks the M from C.obj. You will end up with multiple definitions of M, all with the same implementation. This is a waste of space.
See http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html how to do ifdef guards. You have to start with ifndef before the define.
Edit: Ah no, while your guard is wrong that's not the issue. Put static in front of your function to make it work. Classes are different because they define types.
I don't know what's under the hood, but if you don't need a class I guess that the compiler will automatically add the "extern" key to your functions, so you'll get the error including the header 2 times.
You can add the static keyword to M() method so you'll have only one copy of that function in memory and no errors at compile time.
By the way: I see you have a #endif, but not a #ifdef or #ifndef, is it a copy/paste error?