I'm trying to convert a C++ std::map to C#.
I know that there is a way to do this using std_map.i but it only seems to work if I write for every class a new template like
%template(String_Foo_Map) std::map<std::string, Foo>;
%template(String_Bar_Map) std::map<std::string, Bar>;
...
Is there a way to this is automatically, no matter what type is used? Something like
%template(String_T_Map) std::map<std::string, T>;
and it would create
String_Foo_Map
String_Bar_Map
...
You can define macros for SWIG similarly to how it is done for Numpy
Header file
#include <map>
#include <string>
class A {
public:
A() : m_a(1.0f) {}
float m_a;
};
class B {
public:
B() : m_b(2.0f) {}
float m_b;
};
SWIG interface file
%module test
%{
#include "test.h"
%}
%include "std_map.i"
%include "std_string.i"
%include "test.h"
%define %my_templates(DATA_TYPE)
%template(String_ ## DATA_TYPE ## Map) std::map<std::string, DATA_TYPE>;
%enddef
%my_templates(A)
%my_templates(B)
The example is now complete
Related
Hi imy project recognises double definitions of variables that do not exist 2 times. I suppose that some how by changing my code and recompiling it stucks.
LedMatrix7219.cpp.o:(.data.Alphaletter+0x0): multiple definition of `Alphaletter' LedController.cpp.o:(.data.Alphaletter+0x0): first
defined here
LedMatrix7219.cpp.o:In function `loop'
LedController.cpp.o:(.bss.arr+0x0): first defined here
LedMatrix7219.cpp.o:In function `loop'
LedController.cpp.o:(.data.Alphaletter2+0x0): first defined here
collect2.exe*:error: ld returned 1 exit status
I have a class LedController and a header LettersDefinition.h
All the headers start like this:
I am including a struct and an enum from the LetterDefinition.h to the LedController so at the header i need to include the LetterDefinition.h in order to make a certain struck.
#ifndef __LEDCONTROLLER_H__
#define __LEDCONTROLLER_H__
#include <Arduino.h>
#include "LettersDefinition.h"
LetterStruct finalText;
String theText="Test";
void test();
//it does some extra staff
#endif //__LEDCONTROLLER_H__
And the header of the letter definition.
#ifndef LETTERSDEFINITION_H_
#define LETTERSDEFINITION_H_
#include "arduino.h"
#include <avr/pgmspace.h>
struct LetterStruct{
lettersEnum name;
uint8_t size;
uint8_t columnSize[5];
uint8_t data[18];
}Alphaletter;
#endif /* LETTERSDEFINITION_H_ */
And from my main .ide file i call the test function of the Ledcontroller i a get the error you see above. The test fuction just checks the LetterStruct.name variable nothing more.
My .ide is something like:
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include "LedController.h"
LedController controller;
void setup()
{
//irrelevant inits
}
void loop()
{
controller.test();
delay(2000);
}
If i delete the #include "LettersDefinition.h" from the LedController.h this error gives its place to an error that the LetterStruct is not defined in the LedController.h which is normal since i have to add the LettersDefinition.h in order to be defined.
Your problem originates that you "define" variables in header files. This in general will lead to the multiple definition problem and is not standard design.
The model you need to follow is to define once in a source file:
//some.cpp
// this is define
int variableX = 5;
And declare in the header file:
//some.h
// this is declare
extern int variableX;
Every other source file that includes the header just processes the "extern" line, which says roughly "there is an int variableX that will exist in the final program". The compiler runs over every .cpp .c file and creates a module. For the some.cpp that defines the variable, it will create the variableX. All the other .cpp files will just have the extern reference which is a placeholder. The linker will resolve those placeholders when it combines all the modules together.
In your specific case, this means changing:
// .h file should only be externs:
extern LetterStruct finalText;
extern String theText;
// .cpp file contains definitions
LetterStruct finalText;
String theText="Test";
Instead of doing this for calloc:
TCHAR *sText = (TCHAR *) calloc(1024, sizeof(TCHAR));
I have this at the top of my C++ file:
#define tcalloc(nCharacters) (TCHAR*)calloc(nCharacters,sizeof(TCHAR))
so I can more easily write this:
TCHAR *sText = tcalloc(1024);
Now, how do I do a shorthand for my std::vector statement? This is my code:
std::vector <TCHAR>sText(1024,0);
maybe
typedef std::vector<TCHAR> tcVec;
#define init_1k_charVector tcVec(1024,0)
int main(int, char**)
{
tcVec sText(1024,0);
tcVec sText2 = init_1k_charVector;
...
}
I wanted to use pcl::io::savePNGFile in two source-files in my code.
As soon as I include the required include in second source-file
# include <pcl/io/png_io.h>
the project doesn't compile.
The error message is:
/usr/include/pcl-1.7/pcl/io/png_io.h:86: multiple definition of `pcl::io::saveRgbPNGFile(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char const*, int, int)'
I'm going to wrap the function in a class in order to include it only once in project. But I think it is not the best way. Am I doing something in a wrong way? Is there a better solution?
Thanks!
EDIT
Finally I've implemented a Q&D solution and wrapped the function (only for normal clouds)
cloudsaver.h
#ifndef CLOUDSAVER_H
#define CLOUDSAVER_H
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <string>
class CloudSaver
{
public:
CloudSaver();
void saveCloudToPNG(const std::string & fileName, const pcl::PointCloud<pcl::PointXYZRGBNormal>& cl );
};
#endif // CLOUDSAVER_H
cloudsaver.cpp
#include "cloudsaver.h"
# include <pcl/io/png_io.h>
CloudSaver::CloudSaver()
{
}
void CloudSaver::saveCloudToPNG(const std::string & fileName, const pcl::PointCloud<pcl::PointXYZRGBNormal>& cl )
{
pcl::io::savePNGFile<pcl::PointXYZRGBNormal>(fileName, cl );
}
But I'm still curious, how to do it properly.
As far as I know, There are some issues related to png_io.h.
I have change the definition of PCL_DEPRECATED in png_io.h file with this definition,and every thing becomes OK.
template <typename T>
PCL_DEPRECATED (void savePNGFile (const std::string& file_name, const pcl::PointCloud<T>& cloud),
"pcl::io::savePNGFile<typename T> (file_name, cloud) is deprecated, please use a new generic "
"function pcl::io::savePNGFile (file_name, cloud, field_name) with \"rgb\" as the field name."
);
look at this link [https://github.com/PointCloudLibrary/pcl/pull/300]
I guess you are using the static version of PCL.
To solve this issue you need to declare those methods as inline.
For example, for PCL 1.7.1, you need to edit this file:
pcl-pcl-1.7.1/io/include/pcl/io/png_io.h
And on these lines, add the keyword inline:
85: inline saveRgbPNGFile(...
96: inline savePNGFile(...
107: inline savePNGFile(...
119: inline savePNGFile(...
173: inline savePNGFile(...
Now rebuild the library, and you should be able to compile without any issues.
I'm working on turning some MCMC software written in c++ into an R-package using Rcpp and modules. In this regard I need to maintain a pointer that is a global variable, and that points to the latest object of some class constructed.
Here is a very simple example in the form of an R-script:
require(Rcpp)
require(inline)
inc <- '
using namespace Rcpp;
class test;
test* glob; //global pointer
class test{
private:
double foo;
public:
test(double foo_) : foo(foo_) {
glob=this; // the line causes segfault
};
double get_foo(){return foo;};
};
RCPP_MODULE(test){
class_<test>("test")
.constructor<double>()
.property("foo",&test::get_foo)
;
}
'
fx <- cxxfunction(signature(),plugin="Rcpp",include=inc);
test_module <- Module("test",getDynLib(fx))
test <- test_module$test
t1 <- new(test,1.0)
What I'm trying to get at is something like the following (in c++):
#include<iostream>
class test;
test* glob;
class test{
private:
double foo;
public:
test(double foo_) : foo(foo_) {glob=this;};
double get_foo(){return foo;};
};
int main(){
test t1(1.0);
test t2(2.0);
std::cout << (*glob).get_foo() << std::endl;
}
Which compiles and runs as it should.
Thanks in advance,
Regards, Tore Kleppe
That seems like two unrelated and simple errors.
First off, you need to make that pointer static. Things then work.
Second, using Rcpp Module with inline is no
longer the easiest way around, and we generally recommend using a package -- or Rcpp Attributes as I do below.
Correct code, including explicit messaging to stdout in the constructor:
#include <Rcpp.h>
using namespace Rcpp;
class test;
static test* glob = NULL; //global pointer
class test{
private:
double foo;
public:
test(double foo_) : foo(foo_) {
Rcpp::Rcout << "Seeing foo_ of " << foo_ << " in ctor\n";
glob=this; // the line causes segfault
};
double get_foo(){return foo;};
};
RCPP_MODULE(test){
class_<test>("test")
.constructor<double>()
.property("foo",&test::get_foo)
;
}
Then simple use from the command-line (using littler; R or Rscript are equivalent):
$ r -lRcpp -e 'sourceCpp("/tmp/tore.cpp"); tt <- new(test, 1.23); print(tt$foo)'
Seeing foo_ of 1.23 in ctor
[1] 1.23
$
Note how we can skip all the Module instantiation etc.
Reasonably new to c++, I'm trying to use vectors in my application.
I am using
#include <vector>
in the header file, but when I compile it fails on this line:
std::vector<Shot> shot_list;
Noting the error E2316 'vector' is not a member of 'std'
If I then remove std::, It results in the Undefined symbol 'vector' compiler error message. Really at a loss with this one. Had no issues using
std::list<Shot> shot_list;
prior to using vectors.
Here is a simple example that fails to comile:
//---------------------------------------------------------------------------
#ifndef testclassH
#define testclassH
//---------------------------------------------------------------------------
#include <vector>
class TestClass {
private:
std::vector<int> testVect(1); // removing std:: and adding using namespace std; below the include for the vector it still fails to compile;
};
#endif
To me I don't see any difference between this and This Example
Without clarifying which namespace that the vector is in, you can not use "vector" by itself. (using namespace std;) Maybe you can paste your related code for more spesific help.
Edit:
You can not initialize the vector in the .h. You need to do it in .cpp maybe using the resize() function of the vector. This can be an option for you (using the constructor of the class):
#ifndef testclassH
#define testclassH
//---------------------------------------------------------------------------
#include <vector>
class TestClass {
private:
std::vector<int> testVect;
public:
TestClass()
{
testVect.resize(4);
}
};
#endif
The simple example that you have given compiles if you make the change.