I created a sample ruby extension using C++ class. it works fine when i did not parse the value. but when i parse parameter it show an error. here is my code.
C++ header file
#ifndef CIRCLE_H_
#define CIRCLE_H_
class Circle {
public:
Circle(float radius):_radius(radius) {}
float getArea() { return 3.14159 * _radius * _radius; }
private:
float _radius;
};
CPP file.
#include<ruby.h>
#include"Circle.h"
VALUE method_test(VALUE y){
double x= NUM2DBL(y);
Circle *cir= new Circle(x);
return DBL2NUM(cir->getArea());
}
extern "C" void Init_Test(){
VALUE lemon = rb_define_module("Test");
rb_define_method(lemon, "test", (VALUE(*)(ANYARGS))method_test,1);
}
extconf.rb
require 'mkmf'
have_library( 'stdc++' );
$CFLAGS << " -Wall"
create_makefile( 'Test' );
run.rb
require 'rubygems'
require 'Test'
include Test
puts test(7)
when i execute run.rb it shows an error.
run.rb:7:in `test': can't convert Object into Integer (TypeError)
from run.rb:7:in `<main>'
please help me to solve this problem. thank you.
The line
VALUE method_test(VALUE y) {
Should be
VALUE method_test(VALUE self, VALUE y) {
The error message is thrown by NUM2INT(y) because y is the root Object of the script in your code as-is. The root object is what you got because you mixed in your module at the top level of the script. If you had mixed in to another class, you would have got an instance of that class instead.
All native extension methods should take a self parameter (the first one if you have fixed number of params) which is the context that they are being called in (a Module, Class or instance of a Class). It is how you get foo into the extension when you call foo.test. This might seem odd when both Ruby and C++ do this automatically (self in Ruby, and this in C++): However it is necessary to have self appear as param because the Ruby internal API is written in C, which does not support OO directly - instead the Ruby API defined in ruby.h expects you to write and use C functions that take references to the current object as one of the params.
In addition you are making a call to Circle( int radius ) - which does not exist (although the compiler may be kind and coerce x for you automatically). You probably want to use double variables throughout and use NUM2DBL(y) and DBL2NUM( cir->getArea() )
Related
In Python itself, you'd write simply float(f) where f is a Python Decimal. That yields a double type (called a float in Python).
But I need to do this in boost::python. My code (abridged) is
double toDouble(boost::python::object obj)
{
std::string type = boost::python::extract<std::string>(obj.attr("__class__").attr("__name__"));
std::string module = boost::python::extract<std::string>(obj.attr("__class__").attr("__module__"));
std::string cls = module + "." + type;
if (cls == "decimal.Decimal"){
double f = boost::python::extract<double>(obj);
return f;
}
throw "Oops";
}
But I get an error
No registered converter was able to produce a C++ rvalue of type
double from this Python object of type decimal.Decimal
How do I do this? I can't imagine it's complicated. Clearly I'm missing something.
The code you need in the if block is
static boost::python::object builtins
= boost::python::import("builtins");
static boost::python::object function
= boost::python::extract<boost::python::object>(builtins.attr("float"));
boost::python::object ret = function(obj);
double f = boost::python::extract<double>(ret);
I am indeed essentially using the Python function float(obj).
And by the looks of things, you are already familiar with boost::python::extract.
float is a built-in python function. See https://docs.python.org/3/library/functions.html. So the first statement is the importing of the module containing the built-in functions. The second statement obtains the float function.
The third one calls it, on the lines of the Boost documentation "Calling Python Functions And Methods".
You might be able to pull this together to register this extraction, which probably, knowing the beautiful way in which Boost is designed, amounts to little more than specialising a template.
I try to make a system, where I need a activator function. This activator function may have a state, so I tried to put the state into an concurrency::array_view. When I try to build the solution, I get the following linker error.
Error 2 error LNK2019: unresolved external symbol "public: static double __thiscall ArtNeuroNet::ActivationFunctions::Activator::function(double,class Concurrency::array_view) restrict(cpu, amp)" (?function#Activator#ActivationFunctions#ArtNeuroNet##SENNV?$array_view#N$00#Concurrency###DZ_B) referenced in function _wmain D:\Projekte\ArtNeuroNet\ArtNeuroNet\ArtNeuroNet.obj ArtNeuroNet
Error 3 error LNK1120: 1 unresolved externals D:\Projekte\ArtNeuroNet\Debug\ArtNeuroNet.exe 1 1 ArtNeuroNet
My simplified activator looks like
double Activator::lin_function(double x, concurrency::array_view<double, 1> state)
restrict(cpu, amp)
{
if (x > state[StateParameterType::ThresholdParameter])
return 1;
else if (x < -(state[StateParameterType::ThresholdParameter]))
return 0;
else
return state[StateParameterType::AlphaParameter] * x + 0.5f;
}
double* Activator::getInitialState(double alpha)
{
double stateCpu[] = {1.0, 0.5};
if (alpha != NULL)
stateCpu[0] = alpha;
return stateCpu;
}
My activator creation looks like
Activator activator = *(new Activator());
double* stateCpu = activator.getInitialState(1.0);
concurrency::array_view<double, 1> state(2, stateCpu);
activator.lin_function(0.4, state);
For testing purpose, I added the last line, which is the call activator.lin_function(0.4, state). If I comment that line out, the project gets build without any problems.
My question is now, what am I missing out or am I doing, which I'm acctually not supposed to do?
EDIT
The method lin_function is private. However, in the Activator there's a public method function which calls the private method lin_function. For simplification-reasons, I left that part of the source coude out. Both methods are accessable, as I otherwise wouldn't be able to build the solution, when the call to the method lin_function is commented out.
Activator resides completely within the same project, which is a console-application for now.
The lin_function relies on a single state variable. However, a threshold-implementation of the activator function doesn't need any state storage at all. Changing everything to the threshold-activation function and commenting the rest out reacts the same way. In particular that is „lin_function commented out -> no linker error, otherwise –> linker error“
EDIT 2
For the Activator there exists a header (Activator.h) and source-file (Activator.cpp). It somehow seems that the linker can't find any method from the header which is declared as restrict(cpu, amp).
// Doesn't get found and throws linker error
double Activator::function(double x)
restrict(cpu, amp)
{
return (x >= 0) ? 1 : 0;
}
// Get's found and no linker errors occur
double Activator::function(double x)
{
return (x >= 0) ? 1 : 0;
}
EDIT 3
After defining all methods containing a restrict(amp, cpu) as static in the header-file, everything did build correctly and ran without problems.
Is there actually a restriction on methods needed to be static when restrict(amp, cpu) is used?
Here are the limitations on C++ AMP with respect to classes and functions etc. You are also limited to a subset of supported C++ types but I don't think that is the issue here.
References and pointers (to a compatible type) may be used locally but
cannot be captured by a lambda. Function pointers,
pointer-to-pointer, and the like are not allowed; neither are static
or global variables.
Classes must meet more rules if you wish to use instances of them.
They must have no virtual functions or virtual inheritance.
Constructors, destructors, and other nonvirtual functions are allowed.
The member variables must all be of compatible types, which could of
course include instances of other classes as long as those classes
meet the same rules. The actual code in your amp-compatible function
is not running on a CPU and therefore can’t do certain things that you
might be used to doing:
recursion
pointer casting
use of virtual functions
new or delete
RTTI or dynamic casting
goto
throw, try, or catch
access to globals or statics
inline assembler
This is taken from my book and I apologize because it is misleading. What isn't made clear is that this applies to classes that you wish to pass to AMP kernels as data. Not to classes that have restrict(amp) methods on them. This is only supported for static methods because it is not possible to share the class this pointer with the GPU as it refers to an object instance on the CPU.
So the following is an example of a class that meets the above requirements and can be passed to an AMP kernel:
class stuff
{
public:
int a;
stuff(int v) : a(v) { }
};
stuff also meets the requirements for supported types as int is supported by AMP.
The following class uses stuff in an array_view:
class test_case
{
public:
test_case()
{
}
static int amp_method(int a) restrict(amp, cpu)
{
return a * a;
};
void test_amp()
{
concurrency::array_view<stuff, 1> data(100);
concurrency::parallel_for_each(data.extent,
[data](concurrency::index<1> idx) restrict(amp)
{
data[idx].a = amp_method(data[idx].a);
});
data.synchronize();
};
void test_cpu()
{
std::vector<int> data(100, 0);
for (auto& d : data)
{
d = amp_method(d);
}
}
};
If you remove the static modifier on amp_method then you get the following error on VS 2013.
warning C4573: the usage of 'test_tools_tests::test_case::amp_method'
requires the compiler to capture this but the current default
capture mode does not allow it
You may see something different in 2012. One of the weaknesses of the first AMP release was it's errors. This has improved in 2013.
On reflection this all seems really reasonable. How could I pass this to the GPU when it refers to code running on the CPU?
Note that restrict cannot be applied to classes.
Thanks for highlighting this issue. I guess I should update the book errata.
I'm trying make a shared library in c++ implementing tools for Fermi gases. I'm using the GSL library to solve a function numerically and my code runs without a problem without when running as a script, but when trying to convert it to a shared library and classes I encounter problems.
I've seen similar questions:
Q1
Q2
Q3
I'm fairly new to c++-programming and cannot seem to adapt the different answers to my problem. Probably since I do not quite understand the answers.
My code is:
/* Define structure for the GSL-function: chempot_integrand */
struct chempot_integrand_params { double mu; double T; };
double
ChemicalPotential::chempot_integrand (double x, void * params){
/* Computes the integrand for the integral used to obtain the chemical potential.
*
* This is a GSL-function, which are integrated using gsl_integration_qag.
*/
// Get input parameters.
struct chempot_integrand_params * p = (struct chempot_integrand_params *) params;
double mu = p->mu;
double T = p->T;
// Initiate output parameters for GSL-function.
gsl_sf_result_e10 result;
int status = gsl_sf_exp_e10_e( ( gsl_pow_2(x) - mu ) / T , &result );
if (status != GSL_SUCCESS){
printf ("Fault in calculating exponential function.");
}
// Return (double) integrand.
return (gsl_pow_2(x) / ( 1 + result.val * gsl_sf_pow_int(10,result.e10) ));
}
/* Define structure for the GSL-function: chempot_integration */
struct chempot_integral_params { double T; };
double
ChemicalPotential::chempot_integration (double mu, double T){
/* Computes the integral used to obtain the chemical potential using the integrand: chempot_integrand.
*/
// Set input parameters for the integrand: chempot_integrand.
struct chempot_integrand_params params_integrand = { mu, T };
// Initiate the numerical integration.
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000); // Allocate memory for the numerical integration. Can be made larger if neccessary, REMEMBER to change it in the function call: gsl_integration_qag as well.
double result, error;
gsl_function F;
F.function = &ChemicalPotential::chempot_integrand;
F.params = ¶ms_integrand;
// Upper limit for integration
double TOL = 1e-9;
double upp_lim = - T * gsl_sf_log(TOL) + 10;
gsl_integration_qag (&F, 0, upp_lim, 1e-12, 1e-12, 1000, 6, w, &result, &error);
// Free memory used for the integration.
gsl_integration_workspace_free (w);
return result;
}
and when compiling I get the error
error: cannot convert ‘double (Fermi_Gas::ChemicalPotential::*)(double, void*)’ to ‘double (*)(double, void*)’
in line
F.function = &ChemicalPotential::chempot_integrand;
It is indeed interesting that people ask this over and over again. One reason may be that the proposed solutions are not easy to understand. I for one had problems understanding and implementing them. (the solutions did not work out of the box for me, as you might expect.)
With the help of tlamadon I just figured out a solution that may be helpful here as well. Let's see what you guys think.
So just to recap, the problem is that you have a class that contains a member function on which you want to operate with something from the GSL library. Our example is useful if the GSL interface requires a
gsl_function F;
see here for a definition.
So here is the example class:
class MyClass {
private:
gsl_f_pars *p; // not necessary to have as member
public:
double obj(double x, void * pars); // objective fun
double GetSolution( void );
void setPars( gsl_f_pars * xp ) { p = xp; };
double getC( void ) ; // helper fun
};
The objective of this exercise is to be able to
initiate MyClass test,
supply it with a paramter struct (or write a corresponding constructor), and
call test.GetSolution() on it, which should return whatever the GSL function was used for (the minimum of obj, a root, the integral or whatever)
The trick is now to put have an element in the parameter struct gsl_f_pars which is a pointer to MyClass. Here's the struct:
struct gsl_f_pars {
double a;
double b;
double c;
MyClass * pt_MyClass;
};
The final piece is to provide a wrapper that will be called inside MyClass::GetSolution() (the wrapper is a stand in for the member function MyClass::obj, which we cannot just point to with &obj inside the class). This wrapper will take the parameter struct, dereference pt_MyClass and evaluate pt_MyClass's member obj:
// Wrapper that points to member function
// Trick: MyClass is an element of the gsl_f_pars struct
// so we can tease the value of the objective function out
// of there.
double gslClassWrapper(double x, void * pp) {
gsl_f_pars *p = (gsl_f_pars *)pp;
return p->pt_MyClass->obj(x,p);
}
The full example is a bit too long to post here, so I put up a gist. It's a header file and a cpp file, it should be working wherever you have GSL. Compile and run with
g++ MyClass.cpp -lgsl -o test
./test
This is a duplicate question. See Q1 or Q2 for example. Your problem is the following: you cannot convert pointers to member functions to free function pointers. To solve your problem, there are two options. You can define your member function as static (which is bad in 90% of the case because the member function will not be attached to any instantiation of your class and that is why you can convert it to a free function) or you can use the wrapper you linked that will use a static member functions under the hood to make your code compatible with gsl without the need of declaring your particular member function static.
EDIT #Florian Oswald. Basically your entire solution can be implemented in 2 lines using std::bind the wrapper I cited before
gsl_function_pp Fp( std::bind(&Class::member_function, &(*this), std::placeholders::_1) );
gsl_function *F = static_cast<gsl_function*>(&Fp);
In practice is this is just 1 extra line from a pure C code!
As I stated in a comment, wrapping every member function that you want to integrate using an extra global struct and an extra global function is cumbersome and pollute your code with a lot of extra functions/struct that are completely unnecessary. Why use c++ if we refuse to use the features that make C++ powerful and useful (in comparison to C)?
Another classical Example: if you want to pass a LOT of parameters, use lambda functions (no extra struct or global functions) !!!
To be more precise: Imagine you have 2 parameters (doubles) .
//Declare them (locally) here
double a1 = ...;
double a2 = ...;
// Declare a lambda function that capture all of them by value or reference
// no need to write another struct with these 2 parameters + class pointer
auto ptr = [&](double x)->double {/.../};
// Cast to GSL in 3 lines using the wrapper
std::function<double(double)> F1(ptr);
gsl_function_pp F2(F1);
gsl_function *F = static_cast<gsl_function*>(&F2);
No extra global struct of global functions and no extra wrapper (the same wrapper that solved the problem of integrating member function also solved the problem of integrating a lambda expression). Of course this is a matter of style in the end, but in the absence of these nice features that allow the use of C libraries without code bloat, I would never leave C.
I've observed that when one types
help
in the Python repl, one gets
Type help() for interactive help, ...
and when one types
help()
one gets kicked into help mode. I'm pretty sure this is because site._Helper defines __repr__() (for the first example) and __call__() (for the second).
I like this behavior (prompt for just the object, and callable syntax), and I'd like to do the same for a C++ class I'm exporting to Python via SWIG. Here is a simple example of what I've tried to do
helpMimic.h
-----------
class HelpMimic
{
public:
HelpMimic() {};
~HelpMimic() {};
char *__repr__();
void operator()(const char *func=NULL);
};
helpMimic.cxx
-------------
char *HelpMimic::__repr__()
{
return "Online help facilities are not yet implemented.";
}
void HelpMimic::operator()(const char *func)
{
log4cxx::LoggerPtr transcriptPtr = oap::getTranscript();
std::string commentMsg("# Online help facilities are not yet implemented. Cannot look up ");
if (func) {
commentMsg += func;
}
else {
commentMsg += "anything.";
}
LOG4CXX_INFO(transcriptPtr, commentMsg);
}
helpMimic.i
-----------
%module sample
%{
#include <helpMimic.h>
%}
class HelpMimic
{
public:
HelpMimic() {};
~HelpMimic() {};
char *__repr__();
void operator()(const char *func=NULL);
};
When I attempt to use this class in my application, I can't seem to get the behavior I see with help (the output below is taken from a C++ application with Python embedded, where each input line is sent through PyEval_String()):
tam = sample.HelpMimic()
tam # echoes 'tam', nothing else
print tam
# _5010b70200000000_p_HelpMimic
print repr(tam)
# <Swig Object of type 'HelpMimic *' at 0x28230a0>
print tam.__repr__()
# Online help facilities are not yet implemented.
That last print shows that the method __repr__() is there, but I can't find it using the simpler object reference or using repr(tam). I also tried defining __str()__ in the hopes that I'd misunderstood which would get called, but still no luck.
I've tried using the %extend directive in the interface file to insert a __str__() or a __repr__() definition into the SWIG interface definition file, instead of defining them directly in C++, but to no avail.
What am I missing?
As #flexo suggested in a comment, if you are using the -builtin flag to the SWIG code generator, repr() will not call your __repr__ method. Instead, you need to define a function that fits in the repr slot.
%feature("python:slot", "tp_repr", functype="reprfunc") HelpMimic::printRepr;
As per HelpMimic::printRepr must have a signature that matches the expected signature (tp_repr in Python docs) - it must return a string or unicode object. Another caveat - you can't put the same function in more than one slot, so don't try to use this for tp_str!
I usually use the %extend feature to avoid tailoring the C/C++ to much for a specific target language. E.g.
%extend MyClass {
%pythoncode %{
def __repr__(self):
# How you want your object to be shown
__swig_getmethods__["someMember"] = SomeMemberGet
__swig_setmethods__["someMember"] = SomeMemberSet
if _newclass:
someMember = property(SomeMemberGet,SomeMemberSet)
def show(self):
# You could possibly visualize your object using matplotlib
%}
};
Where you inside the repr function can call basically any function and format the output to suit your needs. Further, you can add properties and define how they map to setters and getters.
If you want to add a __repr__ in the Python code rather than C/C++, you may need to deal with the default swig definition of __repr__ = _swig_repr.
This turns out to be fairly straightforward:
#if defined(SWIGPYTHON)
%pythoncode %{
del __repr__
def __repr__(self):
return 'object representation'
%}
#endif
I used SWIG to generate a Perl module for a C++ program. I have one function in the C++ code which returns a "char pointer". Now I dont know how to print or get the returned char pointer in Perl.
Sample C code:
char* result() {
return "i want to get this in perl";
}
I want to invoke this function "result" in Perl and print the string.
How to do that?
Regards,
Anandan
Depending on the complexity of the C++ interface, it may be easier, faster, and more maintainable to skip SWIG and write the XS code yourself. XS&C++ is a bit of an arcane art. That's why there is Mattia Barbon's excellent ExtUtils::XSpp module on CPAN. It make wrapping C++ easy (and almost fun).
The ExtUtils::XSpp distribution includes a very simple (and contrived) example of a class that has a string (char*) and an integer member. Here's what the cut-down interface file could look like:
// This will be used to generate the XS MODULE line
%module{Object::WithIntAndString};
// Associate a perl class with a C++ class
%name{Object::WithIntAndString} class IntAndString
{
// can be called in Perl as Object::WithIntAndString->new( ... );
IntAndString();
// Object::WithIntAndString->newIntAndString( ... );
// %name can be used to assign methods a different name in Perl
%name{newIntAndString} IntAndString( const char* str, int arg );
// standard DESTROY method
~IntAndString();
// Will be available from Perl given that the types appear in the typemap
int GetInt();
const char* GetString ();
// SetValue is polymorphic. We want separate methods in Perl
%name{SetString} void SetValue( const char* arg = NULL );
%name{SetInt} void SetValue( int arg );
};
Note that this still requires a valid XS typemap. It's really simple, so I won't add it here, but you can find it in the example distribution linked above.
You must have referred to the SWIG tutorial at www.swig.org/tutorial.html
Anyways, since you just want to invoke the function the C function from perl,
1. Type your interface file(having all the function declarations in the wrapper and the module sections).
2. Compile with swig and options.
3. Compile with gcc to create the objects.
4. Compile with gcc options to create the shared object.
5. run the program as follows:
perl
use moduleName;
$a = moduleName::result();
[NOTE: Look into the generated module file(.pm) for the correct funvtion prototype which points to the correct function in the wrapper file.]