SWIG: Unable to ignore a method in a C++ class - c++

I'm trying to wrap a C++ library using Swig, and I'm having trouble with an overloaded method (and it doesn't help that I haven't touched C++ in 18 years :)
Here's a much simplified class structure:
class TView : public TObject, public TStreamable {
public:
virtual TPalette& getPalette() const;
}
class TGroup : public TView {
// ...
}
class TWindow: public TGroup {
virtual TPalette& getPalette() const;
}
The swig file (again, simplified, looks like this):
%module(directors="1") tvision
%feature("director") TApplication;
%feature("director") TProgram;
%feature("director") TProgInit;
%feature("director") TWindow;
%feature("director") TWindowInit;
%feature("director") TView;
%feature("director") TGroup;
// Obviously a shotgun approach hoping one of these works :P
%rename ("$ignore") TWindow::getPalette;
%ignore TWindow::getPalette;
%rename ("getPalette2") "TWindow::getPalette";
//...
%include "tv/view.h"
%include "tv/group.h"
%include "tv/window.h"
When I generate the Java wrappers and try to compile it, I get this error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project tvsample: Compilation failure: Compilation failure:
[ERROR] /home/jdlee/src/turbovision/swig/src/generated/java/com/steeplesoft/turbovision/internal/tvisionJNI.java:[1348,45] incompatible types: short cannot be converted to com.steeplesoft.turbovision.internal.TPalette
[ERROR] /home/jdlee/src/turbovision/swig/src/generated/java/com/steeplesoft/turbovision/internal/TWindow.java:[129,16] getPalette() in com.steeplesoft.turbovision.internal.TWindow cannot override getPalette() in com.steeplesoft.turbovision.internal.TView
[ERROR] return type short is not compatible with com.steeplesoft.turbovision.internal.TPalette
Two things. The first is that TWindow::getPalette should be ignored, but it's not. The second is that SWIG is generating this Java method:
public short getNumber() {
return tvisionJNI.TWindow_number_get(swigCPtr, this);
}
Does anybody have an answer for either issue? Ideally, there should be a single TWindow#getPalette() method that returns TPalette. If I can fix that, it might fix the ignore issue, as I'm only trying to ignore the method to see if I can just get past the compilation issue.
Help? Please? :)

Related

Inherit from Nested class inside inherited class

I have the kinda weird problem which is already described in nested class inherits from nested class, but i start to get a little bit desperate by now.
I have 4 classes in 2 different files (i don't think that really matters), I'll also cut out the non-important stuff from the classes for a better overview
Request.h (With class Request and BaseCtx)
#ifndef REQUEST_H
#define REQUEST_H
#include <string>
#include <map>
class Request
{
public:
Request() {};
Request(Request &orig) {};
class BaseCtx {};
~Request();
/* ... More methods and functions */
private:
/* ... More methods and functions */
};
#endif
Then there is my inherited class in p_TuStRequest.h (TuStRequest and TuStCtx)
#ifndef P_TU_ST_REQUEST_H
#define P_TU_ST_REQUEST_H
/*#include "Request.h"*/
class TuStRequest : public Request {
public:
TuStRequest() {};
TuStRequest(TuStRequest &orig);
TuStRequest(std::string requestData) {};
class TuStCtx : public Request::BaseCtx {
std::string teid;
};
private:
};
#endif
And my compiler (gcc version 4.2.4 (Gentoo 4.2.4-r01.16 p1.1) tells me the following:
p_TuStRequest.h:14: error: expected class-name before '{' token Makefile:431: recipe for target 'p_TuStController.o' failed
For the ones which are not that familiar with compiler versions, vers. 4.2.4 is a little bit before c++11 support (so basically C++98)
Is this some kind if problem because the compiler (which I can't upgrade) is that old and does not support this or did I do something wrong fundamentally?
If this really is a compiler problem, is there a way around it? If i remove the nested class in TuStRequest everything builds fine, but i would need a second structure to prevent the usage of voidpointers (I really don't want to use voidpointers for the context)
PS: Yeah i know, some stuff is still missing (Copy Constructor and so on..) but that shouldn't be the issue here.

LLVM IR OOP inheritance implementation through C++ API

so I'm trying to write down a compiler for an OOP language with a syntax very similar to Java, and I'm stuck at figuring out how inheritance could be implemented.
What I've tried out already is writing a rather basic C++ inheritance example and compiling it with clang -S ${FILES} -emit-llvm.
The C++ code is the following :
a.hpp:
class A {
protected:
int a;
};
b.hpp:
#include "a.hpp"
class B : public A {
private:
int b;
public:
explicit B();
};
b.cpp:
#include "b.hpp"
B::B() : A() {}
main.cpp:
#include "b.hpp"
int main() {
B b;
}
But I honestly find the output to be really confusing indeed...
What I've discovered Googling is that in order to handle virtual methods and overrides I'll have to use vtables (and about that, knowing that I already found this tutorial in the LLVM doc but I didn't find it really helpful, is there a standard way of creating vtables in LLVM)?
I also have quite some doubts about the compilation order...
Let's say I have this source code :
package test;
class Test extends SuperTest {}
Seems pretty clear to me that in order to merge logical and data structures of Test and SuperTest while analyzing Test, SuperTest must have been compiled already, but how do I arrange the compilation such that problems like this cannot arise?
Thanks for the attention.

What am I doing wrong with pure virtual methods and Google Mock?

Intro
I'm having a problem with implementing a pure virtual interface using Google Mock (v1.7.0).
In order to determine the root cause, I've put together pure virtual interface Simple and MockSimple as a test. I believe what I have done here is in line with this Google Mock example.
Yet, when I compile it, I get an error. Why is this? What am I doing wrong?
Simple Test Code
#include "gmock/gmock.h"
#include "gtest/gtest.h"
class Simple
{
public:
virtual ~Simple() {}
virtual int Initialize() = 0;
};
class MockSimple : public Simple
{
public:
MOCK_METHOD0(Initialize, int());
};
TEST(Hello, MockSimple)
{
MockSimple m;
EXPECT_CALL(m, Initialize);
m.Initialize();
}
Compilation Command
g++ -I../gmock/include/ -I../gmock/gtest/include -c test.cpp -o test.o
Error Output
test.cpp: In member function ‘virtual void Hello_MockSimple_Test::TestBody()’:
test.cpp:20:5: error: ‘m.MockSimple::gmock_Initialize’ does not have class type
Need argument list (an empty one, in this case) for the method called in the EXPECT_CALL :)
EXPECT_CALL(m, Initialize());

C++ How to ignore defined method in header file?

i want a compiler (MinGW g++/Linux g++) to ignore some defined stuff in a header file:
class A {
public:
A();
virtual ~A();
IGNORE void methodA(); // = 0 -> not possible
IGNORE void methodB(); // = 0 -> not possible
}
The problem: methodA() and methodB() can't be pure virtual because the class would be later instanciated, so it gives a compiler error. The reason for doing that: i want to have a readable header file, so this methods should be appear in files - the methods are only used as in the QT framework to work as "signals", which are translated as Strings with a macro.
May be it is possible to declare a macro to let it be as annotation? i saw this in the QT5 framework (declared signal methods) but its not working with my code...
What i not want to do: list the methods only as DOC annotation.
Thanks for a idea how to solve that ;)
void methodA(int) = delete; // note: requires C++11
void methodA(double);
will cause a compiler error if you ever try to use methodA(int), but not if you're trying to use methodA(double).
Found a way to ignore methods as described what i want to do:
#define IGNORE __attribute__((unused))
#define METHOD_TO_STRING(a) ""#a
so i can write in header files
class A {
public:
IGNORE void methodA();
void doStuff(const char *stuff);
void methodB() {
doStuff(METHOD_TO_STRING(methodA());
}
};
Now the compiler is happy and i can pass methods as args :)
Thanks for the tips

boost python question

I'm trying to expose one of my classes to python using boost's python module. I have a class called StatusEffect that I'd like to expose to python. To do so, I'm creating this in the StatusEffect.h file after the class definition of StatusEffect
BOOST_PYTHON_MODULE(StatusEffect)
{
boost::python::class_<StatusEffect>("StatusEffect")
.def("GetPriority", &StatusEffect::GetPriority)
.def("GetDescription", &StatusEffect::GetDescription)
.def("GetName", &StatusEffect::GetName);
}
I want to use it inside python from a function declared inside a header as so:
Primaries.h
#include <boost\python.hpp>
#include <StatusEffects\StatusEffect.h>
#include "ScriptDeclarations.h";
extern void Test();
and in Primaries.cpp
#include "Primaries.h"
class StatusEffect;
using namespace boost::python;
class CppClass {
public:
int getNum() {
return 7;
}
};
BOOST_PYTHON_MODULE(CppMod) {
class_<CppClass>("CppClass")
.def("getNum",&CppClass::getNum);
}
void Test()
{
CppClass mClass;
try
{
PyImport_AppendInittab("CppMod", &initCppMod);
PyImport_AppendInittab("StatusEffect", &initStatusEffect);
Py_Initialize();
object main_module((
handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
StatusEffect effect("Haste");
main_namespace["eff"] = ptr(&effect);
handle<> ignored((PyRun_String("print eff.GetName()\n",
Py_file_input,
main_namespace.ptr(),
main_namespace.ptr() ) ));
/*main_namespace["CppClass"] = class_<CppClass>("CppClass")
.def("getNum",&CppClass::getNum);
main_namespace["cpp"] = ptr(&mClass);
handle<> ignored(( PyRun_String("print cpp.getNum()\n",
Py_file_input,
main_namespace.ptr(),
main_namespace.ptr() ) ));*/
}
catch( error_already_set )
{
PyErr_Print();
}
}
however, when I do this, I get the following error:
Error 16 error LNK2001: unresolved external symbol "public: class std::basic_string,class std::allocator > __thiscall StatusEffect::GetDescription(void)" (?GetDescription#StatusEffect##QAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) C:\KHMP\Game_Cpp\KHMPCpp\KHMPCpp\GameCharacter.obj KHMPCpp
I'm quite sure this is related to my python declaration as when I remove that, and the corresponding code from Test() it compiles correctly. If I uncomment the code concerning the CppCLass in Primaries.cpp and use CppClass however, everything works fine. Do python module declarations need to be in the same source file as where they're used? If so, is there some way around that? I'd like to ultimately be able to put all the Python wrappers for my classes in a single header file.
Can anyone guide me as to what I'm doing wrong?
thanks
One thing to note is that your wrapper should be in your StatusEffect.cpp, not StatusEffect.h or a separate CPP file. However, it should be OK anyway, since everything should still get exported. I would also write a test script in Python, instead of trying to test it from C.
There is not enough information to figure out why your code is not working. Some of the things to consider:
Does GetDescription have an implementation? Is it a pure-virtual function?
Is your StatusEffect class in a different module? If it is, is it __dllexport'ed (if you're on Windows)?
The error seems to point at a problem before you get to the boost::python wrapper. Have you tried commenting out your python stuff and just trying to call StatusEffect::GetDescription directly from your test program?