OMNeT++ issue with linking INET - omnet++

During the build of my new OMNeT++ project I have encountered following error:
out/clang-debug//myUdp.o:(.rdata[_ZTI5myUdp]+0x10): undefined reference to 'typeinfo for inet::ApplicationBase'
I have already configured INET reference (Project "myUdp" -> Properties -> Project reference -> inet checkbox selected)
This is INET Makemake configuration: Target tab and Compile tab
This is Makemake configuration of my project (myUdp): Compile tab and Link tab
And the C++ code:
MyUdp.cc
#include <inet/applications/udpapp/UDPBasicApp.h>
class myUdp: public inet::UDPBasicApp {
};
Define_Module(myUdp);
MyUdp.ned
import inet.applications.udpapp.UDPBasicApp;
simple myUdp extends UDPBasicApp {
#class(myUdp);
}
Can somebody help me to solve this error?

That is probably because UDPBasicApp's methods are defined as virtual.
Compare the GCC infos on "vague linking" from http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html, for example this part:
type_info objects
C++ requires information about types to be written out in order to
implement dynamic_cast, typeid and exception handling. For
polymorphic classes (classes with virtual functions), the type_info
object is written out along with the vtable so that dynamic_cast can
determine the dynamic type of a class object at run time. For all
other types, we write out the type_info object when it is used: when
applying typeid to an expression, throwing an object, or referring
to a type in a catch clause or exception specification.
You would need to provide either a definition for the virtual functions in the base class (UDPBasicApp) or declare them pure, because the compiler (GCC or Clang in your case) is trying to determine the right method for the translation unit (where the vtable and typeinfo objects are then created) and it cannot determine it correctly apparently.

Related

Xamarin Binding .AAR Error : 'SecureString' does not implement interface member

I am trying to bind a .AAR library getting the following error
CS0738 'SecureString' does not implement interface member 'ICharSequence.SubSequenceFormatted(int, int)'. 'SecureString.SubSequenceFormatted(int, int)' cannot implement 'ICharSequence.SubSequenceFormatted(int, int)' because it does not have the matching return type of 'ICharSequence'
This is a problem that occurs with binding Java methods with covariant return types.
There are two ways to fix this issue:
(1).Add a partial class declaration for SecureString and explicitly implement SecureString.SubSequenceFormatted(int, int).
(2).Remove the covariance from the generated C# code.
For more information, you can refer to this document https://learn.microsoft.com/en-us/xamarin/android/platform/binding-java-library/troubleshooting-bindings

How to pass unique_ptr object as argument to a class that is a library

I read all the questions and answers related to passing unique_ptr as argument to a class constructor and those answers worked for classes within the exe. But here im trying to pass an unique_ptr object to a class constructor that is pre-compiled as static library.
This class in the library looks something like this,
// Class declaration (in a header file)
class TScreen
{
private:
std::unique_ptr<TProcess> m_process;
public:
__fastcall TScreen(int a, std::unique_ptr<TProcess> i_process);
};
// The constructor definition (in a separate .cpp file)
__fastcall TScreen::TScreen(int a, std::unique_ptr<TProcess> i_process):
m_process(std::move(i_process))
{
}
I will be trying to instantiate the class TScreen in the exe like this,
void TScreen_Main::CallScreen()
{
std::unique_ptr<TProcess> objprocess (new TProcess());
std::unique_ptr<TScreen> objscreen (new TScreen(0, std::move(objprocess)));
}
I compiled the library and imported it to the exe. When i compile the exe, it gives me a link error like this,
[ilink32 Error] Error: Unresolved external '__fastcall TScreen::TScreen(int, std::unique_ptr<TProcess, std::default_delete<TProcess> >)' referenced from TSCREEN_MAIN.OBJ
[ilink32 Error] Error: Unable to perform link
I tried the same with boost::shared_ptr as well and it gives me the same error. But it works fine with raw pointers, but not with smart pointers and i cannot figure out why?
Thanks in advance.
Your problem here is a linking issue. Now, exactly what's going on is difficult for me to say because I never work in a Windows environment, and linking is something that (while very similar) has some distinct differences between a Unix/Linux and a Windows environment.
My guess is that if you explicitly declare your constructor to be inline, and declare that the definition is inline, it will work correctly.
This presumes that the fact that you put the declaration of the class and definition together indicates that the definition is in the header file with the class.
When the compiler sees that it's declared inline it will emit a definition into every compilation unit where it's needed. The linker should then eliminate all the duplicate definitions.
If you really are defining the constructor in some .cpp file separate from the .hpp file that the class is in, and you compiler that .cpp file into .obj file that eventually makes it into a .lib or .dll that you link against when creating the executable, then I don't know what the problem is. If this is the case, you should use the tools that should come with your development environment to see what symbols are actually in the library or the dll because somehow the symbol for the constructor definition isn't there.

IllegalAccessError Java 8 Method reference with package visibility class [duplicate]

Error while executing below code,
Caused by: java.lang.IllegalAccessError: tried to access class
com.google.common.collect.AbstractTable from class
ImmutableTable.copyOf(listItemsToProcess.parallelStream()
.map(item ->
ProcessorInstanceProvider.getInstance()
.buildImmutableTable(item))
.collect(() -> HashBasedTable.create(),
HashBasedTable::putAll,
HashBasedTable<Integer, String,
Boolean>::putAll)
);
Error in coming on - HashBasedTable::putAll Using Oracle's 1.8 jre
This is a compiler bug, related reports are
JDK-8152643: “Javac compiles method reference that allows results in an IllegalAccessError”
JDK-8059632: “Method reference compilation uses incorrect qualifying type”
Note that the first report has the status “Fixed in 8u102”, so downloading JDK8u102 could solve the issue. Of course, when using a compiler other than javac, e.g. ECJ, you have to ensure that that compiler is up to date as well.
In either case, you have to recompile the source code, as it is a compiler issue. But then, the compiled code should even work with older JREs.
To explain the issue, normally, invocations should be encoded into the byte code using the compile-time type of the receiver (or the explicit type in case of static methods), regardless of the declaring type of the actual method implementation. So if you have a public class A inheriting the public method foo from the non-public class B, an invocation of A.foo should be encoded as A.foo rather than B.foo. For ordinary invocations, the compilers work that way, but for method references, javac (and afaik also older versions of ECJ) failed to do that correctly. So when encountering a class trying to access B.foo directly without having access to B, an IllegalAccessError is thrown.
It works when using a lambda expression instead, as then, the invocation is compiled into an ordinary invocation instruction, for which the compiler works correctly, within a synthetic method and a reference to that synthetic method is used when constructing an instance of the functional interface at runtime. Since the synthetic method recides within the same class, it’s always accessible.
AbstractTable was introduced in Guava version 15. Take a look at your classpath configuration; you're probably using an earlier library version at runtime.
Interesting, i replaced method references with Lambda expression and it worked.
ImmutableTable.copyOf(itemList.parallelStream()
.map(item ->
ProcessorInstanceProvider.get()
.buildImmutableTable(item))
.collect(() -> HashBasedTable.create(),
(a, b) -> a.putAll(b),
(a, b) -> a.putAll(b))
);

check_and_cast() error in Omnet++

I'm simulating network in Omnet++, with INET framework. I want to get the position (coordination x & y) of node. So I do this code:
cModule *host = getContainingNode(this);
IMobility *mobility = check_and_cast<IMobility *>(host->getSubmodule("mobility"));
... = mobility -> getCurrentPosition();
But, when I ran the simulation, I got this error
check_and_cast(): cannot cast nullptr to type 'inet::IMobility *'
Can you explain to me this error?
As I see, if the simulator notify that, so host->getSubmodule("mobility") is nullptr?
By the way, I have define mobilityType in the NED file and include IMobility.h
The NED code you shared shows that you have a simple module that implements the IMobility interface, while the C++ code looks like something that is inside a simple module which is INSIDE a compound module that represent the network host and this compound module also contains a separate simple module called "mobility" that implements the IMobility interface. (this is how code is implemented in INET).
You should either:
arrange your code so you have a compound module as a networkNode with several simple modules inside it (one of them is the mobility module).
if you insist having a simple module which already implements the IMobility interface (in C++) then you already have access to the position on that object using the getCurrentPosition method.
I assume (and recommend) that you co on the first route, so you should reaarange your NED file.

Calling a property on the const reference

I have C++/CLI class that defines a property:
public ref class AbstractOffer
{
public:
AbstractOffer();
property String^ Body;
};
In some function the AbstractOffer class is passed by const ref
foo(const AbstractOffer^ ao)
{
ao->Body;
}
When I call the property the method compiler gives the following error :-
error C2662: 'ivrworx::interop::AbstractOffer::Body::get' : cannot
convert 'this' pointer from 'const ivrworx::interop::AbstractOffer'
to 'ivrworx::interop::AbstractOffer %' 1> Conversion loses
qualifiers
It seems somehow connected to const. How can I call the Body property of the object if the object reference is passed by const?
The const qualifier is a problem in C++/CLI. It is only meaningful when it can be checked and that's not in general possible in .NET. It is of course not a problem when you only have one kind of compiler and that compiler follows strict language rules. Like C++. But .NET supports many languages, your method could be easily called from a Cobol.NET program for example. The odds of ever getting const-correctness added to the Cobol language are zero.
The compiler does compile code with const qualifiers and does make an effort to check when it can. Which is why you got the diagnostic. That can even work when the declaration exists in another assembly, as long as it was compiled with C++/CLI, the compiler emits modopt annotations in the metadata.
But there are limitations with that. Properties are one of them, you can't add the const qualifier to the getter, or a member function in general, you'll get slapped with C3842.
Best thing to do is to use C++/CLI for what it is good at, it is an interop language. And const qualifiers just don't work well in an interop scenario.
The only way I know to get round this is the cast away the const-ness. As long as you don't modify the object, it should be fine. (If you do modify it, I've no idea what the outcome will be).
i.e. change your function to be
void foo(const AbstractOffer^ ao)
{
const_cast<AbstractOffer^>(ao)->Body;
}

Resources