I have problems passing D struct that contains static array to C.
D code:
extern (C){
struct vec3f{
float[3] array;
}
void testVec3f(vec3f v);
}
...
void test(){
float[3] ar = [1f,2f,3f];
vec3f v = vec3f(ar);
testVec3f(v);
}
C code:
extern "C" struct vec3f{
float array[3];
};
extern "C" void testVec3f(vec3f a){
printf("x=%f, y=%f, z=%f\n", a.array[0], a.array[1], a.array[2]);
}
Result: x=0.000000, y=0.000000, z=0.000000.
I also checked that both structs in D and C have the same size - 12 bytes.
You are going to run into a whole host of trouble trying to pass structs by value between C and D; especially if your D compiler uses gnu compiler on the back end whereas you may be using clang++ for some parts of your project.
The way gnu c++ and clang++ treat object passing is different, extern "C" adds another layer of complexity. You are best off avoiding all of that and pass your values by reference:
Here your example (working correctly) using clang-c++ and dmd:
test.d:
import std.stdio;
struct vec3f {
float [3] array;
}
extern (C) {
void print_vec3f(vec3f *v);
}
void main()
{
vec3f v = vec3f([1f, 2f, 3f]);
print_vec3f(&v);
}
vect3.cc:
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
struct vec3f {
float array[3];
};
void print_vec3f(struct vec3f *v)
{
printf("x: %f, y: %f, z: %f\n", v->array[0], v->array[1], v->array[2]);
}
#ifdef __cplusplus
};
#endif
Compile using:
clang++ -o vect3.o -c vect3.cc
dmd test.d vect3.o
./test
x: 1.000000, y: 2.000000, z: 3.000000
Related
I tried to initialize an array using __auto_type in GNU C, but this seems to be a syntax error:
#include <stdio.h>
int main() {
__auto_type a[] = {1,2,3,4};
printf("%d",a[0]);
return 0;
}
As a workaround, I can define a variadic macro to initialize the array using typeof, but this is more cumbersome:
#include <stdio.h>
#define infer_array_type(a,b,...) typeof(b) a[] = {b,__VA_ARGS__}
int main() {
infer_array_type(a,1,2,3,4);
printf("%d",a[0]);
return 0;
}
Is it not possible to initialize arrays in GNU C using __auto_type instead of typeof?
In GNU C, it is possible to define a statement expression that returns an array, so the array can be initialized using __auto_type:
#include <stdio.h>
#define infer_array_type(b,...) ({typeof(b) a[] = {b,__VA_ARGS__}; a;})
int main() {
__auto_type a = infer_array_type(1,2,3,4);
printf("%d",a[0]);
return 0;
}
I'm trying to use controlled stepper in boost odeint with thrust::host_vector container and thrust::complex<double> data type. The following code compiles when I use std::vector and std::complex<double>, however when I use thrust container and/or data type, compiler throws an error.
Secondly, the error occurs only when I use a controlled stepper and the simple stepper works with thrust (you can uncomment the appropriate parts of the code). Is there a mistake in my code or is it coming from odeint?
#include <iostream>
#include <vector>
#include <complex>
#include <thrust/host_vector.h>
#include <thrust/for_each.h>
#include <thrust/transform.h>
#include <thrust/complex.h>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/thrust/thrust.hpp>
using namespace boost::numeric::odeint;
typedef std::complex<double> c_type;
typedef std::vector<c_type> state_vec;
//typedef thrust::complex<double> c_type;
//typedef thrust::host_vector<c_type> state_vec;
template<typename data_type, typename complex_type>
struct multiply {
data_type a;
multiply (data_type a): a(a) {}
complex_type operator()(const complex_type& x){
return -a*x;
}
};
template<typename state_type, typename data_type>
struct exp_system {
const data_type gamma;
exp_system (data_type gamma): gamma(gamma) {}
void operator()(const state_type &x, state_type &dxdt, const data_type){
thrust::transform(x.begin(), x.end(), dxdt.begin(),
multiply<data_type, c_type>(gamma));
}
};
int main()
{
state_vec x(2);
x[0] = c_type(1.0, 0.0);
x[1] = c_type(0.10, 0.0);
double gamma = 0.15;
double t_final = 10.0;
runge_kutta_dopri5<state_vec> stepper;
auto c_stepper = make_controlled(1.E-5, 1.E-5, stepper);
auto n_steps = integrate_adaptive(c_stepper,
exp_system<state_vec, double>(gamma),
x , 0.0 , t_final, 0.01 );
//auto n_steps = integrate_adaptive(stepper,
// exp_system<state_vec, double>(gamma),
// x, 0.0, t_final, 0.01);
std::cout << n_steps << std::endl;
return 0;
}
I have a problem with a Template function inside a class. When I call "Set" in something() function, VS show me:
Error C2275 'T': illegal use of this type as an expression
The header is:
#include <vector>
#include <array>
#include <iostream>
using t_double = double;
template<typename T>
using t_vec = std::vector<T>;
class SuperPixel2
{
t_vec<double> distances;
template<typename T>
void Set(t_vec<T> &v,
size_t i,
size_t j,
const T &val);
void something();
}
And the cpp file:
#include "SuperPixel2.h"
template<typename T>
void SuperPixel2::Set(t_vec<T> &v,
size_t i,
size_t j,
const T &val)
{
v[i * cols + j] = T;
}
void SuperPixel2::something()
{
t_double d;
//..
Set(distances, k, l, (t_double)d);
//..
}
In addition to what sudo make install said, you generally cannot declare a template in a header file and write the implementation in a cpp file. See here for an answer to your problem.
Well this line looks pretty odd:
v[i * cols + j] = T;
I think it's meant to be:
v[i * cols + j] = val;
As a side note (and maybe this would make more sense looking at the whole class), the type of distances is known (a vector of doubles), so it's unclear to me why the Set method needs to be a templated member.
I'm using gcc 5.1.0 (c++14) and I was trying with constexpr. Is very annoying to verify if the constexpr I've implemented are evaluated at compile time. I couldn't find any flag for get a warning about that situation.
Here is an example:
example.cpp -----------------------------------------
#include <stdlib.h>
const char pruVar[] = "12345678901234567";
[[gnu::noinline]] constexpr unsigned int myStrlen(const char* cstr)
{
unsigned int i=0;
for(;cstr[i]!=0;++i);
return i;
}
struct CEXAMPLE
{
unsigned int size;
constexpr CEXAMPLE(const char* s): size(myStrlen(s))
{
}
};
int main(void)
{
CEXAMPLE c(pruVar);
unsigned int size = myStrlen(pruVar);
void* a = malloc(c.size + size);
if (a != nullptr)
return 0;
else
return 1;
}
In the example CEXAMPLE::CEXAMPLE is evaluated at compile time including the call to myStrlen in it, but the call to myStrlen in main is being evaluated at runtime. The only way I have to know this is looking at the assembler.This website is very useful too: http://gcc.godbolt.org/
If you know how to make the compiler warn about this or something similar I'll appreciate it
myStrlen(pruVar) can be evaluated at compile time; the compiler is just choosing not to in this instance.
If you want to force the compiler to evaluate it at compile time or error if this is not possible, assign the result to a constexpr variable:
constexpr unsigned int size = myStrlen(pruVar);
^^^^^^^^^
You could also use an enum, or a std::integral_constant:
enum : unsigned int { size = myStrlen(pruVar) };
std::integral_constant<unsigned int, myStrlen(pruVar)> size;
Based on the fact that template arguments must be evaluated at compiletime a helper template can be used.
namespace helper {
template<class T, T v> constexpr T enforce_compiletime() {
constexpr T cv = v;
return cv;
}
}
#define compiletime(arg) ::helper::enforce_compiletime<decltype(arg), (arg)>()
This allows compile time enforcement without an additional constexpr variable, which is handy in order to calculate value lookup tables.
constexpr uint32_t bla(uint8_t blub) {
switch (blub) {
case 5:
return 22;
default:
return 23;
}
}
struct SomeStruct {
uint32_t a;
uint32_t b;
};
SomeStruct aStruct = {compiletime(bla(5)), compiletime(bla(6))};
I'm attempting to compile the example code relating to the ODE solver, gsl/gsl_odeiv2, using g++. The code below is from their website :
http://www.gnu.org/software/gsl/manual/html_node/ODE-Example-programs.html
and compiles fine under gcc, but g++ throws the error
invalid conversion from 'void*' to 'int (*)(double, const double*, double*, double*,
void*)' [-fpermissive]
in the code :
#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
int func (double t, const double y[], double f[], void *params)
{
double mu = *(double *)params;
f[0] = y[1];
f[1] = -y[0] - mu*y[1]*(y[0]*y[0] - 1);
return GSL_SUCCESS;
}
int * jac;
int main ()
{
double mu = 10;
gsl_odeiv2_system sys = {func, jac, 2, &mu};
gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
int i;
double t = 0.0, t1 = 100.0;
double y[2] = { 1.0, 0.0 };
for (i = 1; i <= 100; i++)
{
double ti = i * t1 / 100.0;
int status = gsl_odeiv2_driver_apply (d, &t, ti, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
printf ("%.5e %.5e %.5e\n", t, y[0], y[1]);
}
gsl_odeiv2_driver_free (d);
return 0;
}
The error is given on the line
gsl_odeiv2_system sys = {func, jac, 2, &mu};
Any help in solving this issue would be fantastic. I'm hoping to include some stdlib elements, hence wanting to compile it as C++. Also, if I can get it to compile with g++-4.7, I could more easily multithread it using C++11's additions to the language. Thank you very much.
It looks like you have some problems with Jacobian. In your particular case you could just use NULL instead of jac in the definition of your system, i.e.
gsl_odeiv2_system sys = {func, NULL, 2, &mu};
In general you Jacobian must be a function with particular entries - see gsl manual - that is why your compiler is complaining.
Also, you may want to link the gsl library manually:
-L/usr/local/lib -lgsl
if you are on a linux system.