Ich möchte eine Liste von Zeigern von C++ zu Tcl zurückgeben. Und dann rufen Sie einige Mitgliedsfunktionen mit den Zeigern auf. SWIG kann mir dabei helfen.Swig: Wie man eine Liste von Zeigern von C++ zu Tcl zurückgibt
Allerdings SWIG geben Sie mir eine Liste von Zeiger auf Zeiger.
% getLongTime 10
_30a8620000000000_p_p_MyData _30bc620000000000_p_p_MyData
Ich kann die Syntax zur Dereferenzierung in SWIG nicht finden. Also muss ich für jede Klasse Dereferenzierungsfunktionen schreiben. Es ist sehr unpraktisch.
Ich schließe "std_vector.i" ein, um die Zeigerliste zurückzugeben. Hat jemand ein Beispiel, das Vektor aber ohne zweiten Zeiger verwendet? Oder irgendeine alternative Lösung ist in Ordnung!
Ich habe auch eine allgemeine dereferenzieren Funktion zu schreiben versucht, wie:
void * dereference(void ** p){ return *p; }
Allerdings funktioniert es nicht. Tcl gibt mir Typfehler:
Ich vereinfachte meinen Code, wenn Sie mein Programm versuchen möchten. Hier mein main.cpp ist:
#include <cstdlib>
#include <vector>
using namespace std;
#include "main.hh"
#include <tcl.h>
std::vector<MyData> MyData::AllTime; // It seems the place of this statement matters
std::vector<MyData*> getLongTime(int limit) {
vector<MyData*> longTime;
for(int i = 0; i <= 3; ++i)
if (MyData::AllTime[i].getMinute() >= limit)
longTime.push_back(&MyData::AllTime[i]);
return longTime;
}
MyData* derefMyData(MyData** p) {return *p;} // I have to write a dereference function for every class
/// print command, exectue it and print resulte
void print(Tcl_Interp *interp, const char *command) {
printf("%% %s\n", command);
Tcl_Eval(interp, command);
const char *msg = Tcl_GetStringResult(interp);
if (*msg != '\0')
printf("%s\n", msg);
}
int main(int argc, char** argv) {
Tcl_Interp *interp = Tcl_CreateInterp();
Tcl_Eval(interp, "load ./swig.so swig");
MyData::AllTime.push_back(MyData(10));
MyData::AllTime.push_back(MyData(15));
MyData::AllTime.push_back(MyData(9));
// set the time exceeding 10 to 10 by tcl function.
print(interp, "set times [getLongTime 10]");
print(interp, "foreach t $times { [derefMyData $t] setMinute 10}");
printf("All times:");
for(std::vector<MyData>::iterator i = MyData::AllTime.begin(); i != MyData::AllTime.end(); ++i)
printf("%d ", i->getMinute());
printf("\n");
Tcl_DeleteInterp(interp);
return 0;
}
Hier ist meine main.hh
#ifndef MAIN_HH
#define MAIN_HH
#include <cstdlib>
#include <stdio.h>
#include <vector>
using namespace std;
class MyData{
int minute;
public:
MyData(int minute):minute(minute){};
int getMinute(){return minute;};
void setMinute(int m){ minute = m; };
static std::vector<MyData> AllTime;
};
std::vector<MyData*> getLongTime(int limit);
MyData* derefMyData(MyData** p);
#endif /* MAIN_HH */
hier mein swig.i ist
/* swig.i */
%module swig
%{
#include "main.hh"
%}
%include "std_vector.i"
namespace std {
%template(myDataVector) std::vector<MyData *>;
}
class MyData{
public:
MyData(int minute);
void setMinute(int m);
};
extern std::vector<MyData*> getLongTime(int limit);
extern MyData* derefMyData(MyData** p);
Hier ist meine Kompilierung Befehle
swig -c++ -tcl swig.i
g++ -fpic -c main.cpp swig_wrap.cxx
g++ -shared main.o swig_wrap.o -o swig.so ;# I don't need to compile with main.o in my original program.
g++ main.o -o swig.out -g -I/usr/local/include -L/usr/local/lib -ltcl8.5
setenv LD_LIBRARY_PATH /usr/local/lib:/usr/local/lib
./swig.out
Und hier ist der Ausgang:
% set times [getLongTime 10]
_30a8620000000000_p_p_MyData _80bb620000000000_p_p_MyData
% foreach t $times { [derefMyData $t] setMinute 10}
All times:10 10 9
By the way, das vereinfachte Programmbericht * glibc erkannt *
Ich weiß nicht, wie es zu beheben.
Glücklicherweise ist mein ursprüngliches Programm in Ordnung.
Wenn jemand weiß, wie es zu beheben ist. Lass es mich wissen, bitte.
Meine SWIG Version: 1.3.29
Meine gcc Version: 4.5.2
Richtig gesprochen sollten Sie 'Tcl_FindExecutable (argv [0]);' von 'main' aufrufen, bevor Sie' Tcl_CreateInterp' ausführen, da dies die Tcl-Bibliothek initialisiert, obwohl ich nicht denke, dass das die Dinge für Sie repariert . –