confusing notation in C++ (OMNeT++) - c++

While going through the OMNeT tutorials given at: http://www.omnetpp.org/doc/omnetpp/tictoc-tutorial/part2.html at tutorial 9 I came across some confusing notation:
void Tic9::sendCopyOf(cMessage *msg)
{
cMessage *copy = (cMessage *) msg->dup();
send(copy, "out");
}
The code is pretty short and neat, however due to the fact that I have little experience with C++ / OMNeT I could not understand what this line here does: cMessage *copy = (cMessage *) msg->dup(); , more specifically the (cMessage *). I know msg->dup() actually means (*msg).dup().
Could anyone please elaborate, what actually happens in the memory?
post Edit Addendum:
code for dup():
virtual cMessage *dup() const
{
return new cMessage(*this);
}
description for dup(): Creates and returns an exact copy of this object.
Does this mean that (cMessage *) msg->dup() internally passes the address of object returned by msg->dup() to *copy?
The other confusing notation:
cMessage *Tic9::generateNewMessage()
{
// Generate a message with a different name every time.
char msgname[20];
sprintf(msgname, "tic-%d", ++seq);
cMessage *msg = new cMessage(msgname);
return msg;
}
What does the * in front of class name mean here: *Tic9::generateNewMessage()

Let us assume that msg->dup() returned void * -- that is, a pointer to void, which means a pointer whose type the compiler doesn't track. But you may know, e.g. because of documentation on that function, or because certain preconditions have been met, that msg->dup() will return a pointer to CMessage. Before you can use the return value as such, you need to tell the compiler what the type actually is. You do that by casting the void * to CMessage *, which uses the syntax you see.

Nothing happens in memory. It is just a C-style type cast.
http://en.cppreference.com/w/cpp/language/explicit_cast
You might want to learn more about the basics of the language. C++ is a tricky one to use.

Related

C Style cast and C++ static_cast to reference of pointer

This is NOT C++11
I'm interested in the 3rd parameter of Microsoft's
CMapStringToOb::GetNextAssoc, which has following definition:
void GetNextAssoc(
POSITION& rNextPosition,
CString& rKey,
CObject*& rValue
) const;
Then I've got following easy code for testing: two good cases and one case with compiler error.
class CMyObject : public CObject //in order to use CMapStringToOb
{
public:
CMyObject(CString name_)
:name(name_)
{
}
void SayHello()
{
TRACE(_T("hello") + name);
}
CString name;
};
void main()
{
CMapStringToOb myMap;
myMap.SetAt(_T("a"), new CMyObject(_T("aaa")));
myMap.SetAt(_T("b"), new CMyObject(_T("bbb")));
myMap.SetAt(_T("c"), new CMyObject(_T("ccc")));
//good case 1
POSITION pos = myMap.GetStartPosition();
while (pos)
{
CString s;
CMyObject* pMine = NULL;
myMap.GetNextAssoc(pos, s, (CObject*&)pMine);
if(pMine)
{
pMine->SayHello();
}
}
//good case 2
pos = myMap.GetStartPosition();
while (pos)
{
CString s;
CObject* pObject = NULL;
myMap.GetNextAssoc(pos, s, pObject);
if(pObject)
{
CMyObject* pMine = static_cast<CMyObject*>(pObject);
pMine->SayHello();
}
}
//bad case:
//can not compile
// error C2440: 'static_cast' : cannot convert from 'CMyObject *' to 'CObject *&'
// static_cast and safe_cast to reference can only be used for valid initializations or for lvalue casts between related classes
pos = myMap.GetStartPosition();
while (pos)
{
CString s;
CMyObject* pMine = NULL;
myMap.GetNextAssoc(pos, s, static_cast<CObject*&>(pMine)); //compile error
if(pMine)
{
pMine->SayHello();
}
}
}
All I was trying to do is find an proper way to replace the C style casting to C++ style cast in this case.
Reading from this, it mentioned:
C casts are casts using (type)object or type(object). A C-style cast
is defined as the first of the following which succeeds:
const_cast
static_cast (though ignoring access restrictions)
static_cast (see above), then const_cast
reinterpret_cast
reinterpret_cast, then const_cast
Q1: Was the above list missing anything (e.g. for rValue)?
Q2: What's the proper way of translate C style cast to C++ style cast in this case ? (good case 2 works, but, is there a more concise one?)
Q3: How is the C Style cast doing for rValue? (in other words, please explain why good case 1 works)
You can't static_cast between references (or pointers) to "unrelated types." While you could static_cast from a CMyObject* to a CObject*, that isn't what you're doing here. Here you're trying to cast a reference to a pointer into a reference to another pointer. And the two pointer types do not have an inheritance relationship.
I like your "good case 2" code--I'd run with that.
For more details on the non-relatedness of your pointer types, see here: static_cast and reference to pointers
Inspired by John Zwinck, I will look from a different angle:
static_cast<CObject*>(pMine)
will succeed because type "CMyObject" generalize from type "CObject"; actually, this is done implicitly;
static_cast<CMyObject*>(pObject)
will succeed because type "CMyObject" generalize from type "CObject";
static_cast<CObject**>(&pMine)
will FAIL because type "CMyObject*" does NOT generalize from type "CObject*";
reinterpret_cast<CObject**>(&pMine)
will succeed at compile time because of "reinterpret_cast"; how about run time?
Let's make an assumption of the possible new implementation:
void CMapStringToOb::GetNextAssoc(
POSITION& rNextPosition,
CString& rKey,
CObject** ppValue)
{
*ppValue = (the pointer at the current position, point to an instance of "CMyObject");
}
So with calling this function by:
GetNextAssoc(pos, s, reinterpret_cast<CObject**>(&pMine))
the result is that "pMine" is pointing to an instance of "CMyObject";
So runtime is SAFE.
However, if we insert the key-value by (Note: CYourObject has no generalize relationship to CMyObject)
myMap.SetAt(_T("a"), new CYourObject(_T("aaa")));
and get it out by
GetNextAssoc(pos, s, reinterpret_cast<CObject**>(&pMine));
Compile time will still succeed, however, pMine is now pointing to "CYourObject", which will be UNDEFINED BEHAVIOR at runtime. (static_cast has the same issue, though)
The proper way to write that code would be to use std::map<>. Even if you insist on keeping the existing code mostly, consider fixing the interface of GetNextAssoc() to just return the pointer. In order to do that, you could simply add an overload of that function:
CObject* GetNextAssoc(
POSITION& rNextPosition,
CString& rKey,
) const {
CObject* res = 0;
GetNextAssoc(rNextPosition, rKey, res);
return res;
}
Even more, you could template that function and do the conversion to the target type there. Also, you could then use dynamic_cast, which should be used because formally, the container stores CObjects and they could have various, different types.
Now, why did I partially ignore your question? The reason is that the MFC don't follow modern coding style and in some cases, they simply do things that are frowned on. There are a bunch of justifications for that behaviour, but foremost it is age (didn't know better, didn't have proper template support) combined with compatibility concerns (can't change that now). That's not a reason to repeat these mistakes though.

Correct __bridge usage with ARC and C++ interop? (how to avoid memory leaks?)

I have a bit of pure C++ code which is reading from Objective-C data structures with the help of a function pointer to a method in an Objective C class. I'm treating the Objective-C class instance to read from as an opaque pointer. For example, the C++ method that does the reading has a signature like this:
typedef void(*DataGetterFunc)(void * dataSource, int key, int * outValue);
...
void readData(void * dataSource, DataGetterFunc dataReadingFunc);
When I call the C++ method from Objective-C, I do the following:
MYDataStructure * objectiveCData;
cppObject->readData((__bridge void*)objectiveCData, DataGetterFuncImpl);
Finally, DataGetterFuncImpl dereferences the Objective-C class like so:
void DataGetterFuncImpl(void * dataSource, int key, int * outValue)
{
MYDataStructure * objCData = (__bridge MYDataStructure*)dataSource;
...
}
Originally in DataGetterFuncImpl I was using __bridge_transfer, but then I was getting EXC_BAD_ACCESS the next time ARC called retain on MYDataStructure, So I assumed it was being over-released by the use of __bridge_transfer and changed it to just __bridge.
Are there any memory leaks I should look for by just using __bridge, or do I need to use some combination of __bridge_retain and __bridge_transfer in this case?
When you're using __bridge to convert to or from objc, owership is just not affected. That means, that while you're using the object in C++ you must make sure that there's still a strong reference around.
If you, on the other hand, use __bridge_retain to convert to void* and __bridge_transfer to convert back to id (or any other retainable object type), you must make sure that each __bridge_retain is matched by exactly one __bridge_transfer later.

How to make a getter function for a double pointer?

I am needing to modify an open source project to prevent reusing code (more efficient just to create a GetGameRulesPtr() function than to keep going into the engine to retrieve it. The problem is, it is stored as void **g_pGameRules. Ive never really grasped the concept of a pointer to a pointer, and I am a bit confused.
I am creating a GetGameRules() function to retrieve this pointer, but im not sure if my getter function should be void* ret type and then return *g_pGameRules, or how exactly I should go about this. I am actually brushing on my pointer usage now, but wanted to find out the proper method to learn from.
Here is the code, lines 58-89 are the SDK function that retrieve the g_pGameRules pointer from the game engine. The other functions are what I am adding the getter function to.
// extension.cpp
class SDKTools_API : public ISDKTools
{
public:
virtual const char *GetInterfaceName()
{
return SMINTERFACE_SDKTOOLS_NAME;
}
virtual unsigned int GetInterfaceVersion()
{
return SMINTERFACE_SDKTOOLS_VERSION;
}
virtual IServer *GetIServer()
{
return iserver;
}
virtual void *GetGameRules()
{
return *g_pGameRules;
}
} g_SDKTools_API;
// extension.h
namespace SourceMod
{
/**
* #brief SDKTools API.
*/
class ISDKTools : public SMInterface
{
public:
virtual const char *GetInterfaceName() = 0;
virtual unsigned int GetInterfaceVersion() = 0;
public:
/**
* #brief Returns a pointer to IServer if one was found.
*
* #return IServer pointer, or NULL if SDKTools was unable to find one.
*/
virtual IServer* GetIServer() = 0;
/**
* #brief Returns a pointer to GameRules if one was found.
*
* #return GameRules pointer, or NULL if SDKTools was unable to find one.
*/
virtual void* GetGameRules() = 0;
};
}
// vglobals.cpp
void **g_pGameRules = NULL;
void *g_EntList = NULL;
void InitializeValveGlobals()
{
g_EntList = gamehelpers->GetGlobalEntityList();
char *addr;
#ifdef PLATFORM_WINDOWS
/* g_pGameRules */
if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
{
return;
}
int offset;
if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
{
return;
}
g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
#elif defined PLATFORM_LINUX || defined PLATFORM_APPLE
/* g_pGameRules */
if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
{
return;
}
g_pGameRules = reinterpret_cast<void **>(addr);
#endif
}
You want to return a void*, and do the casting back to the appropriate SomeType** within implementation code. This is because void** has strange semantics (which I can't find on google right now). It also tells more info to the user than they really need. The whole point of using void* to begin with was to avoid giving information to the user that they don't need.
If it is an option, I'd personally recommend avoiding void* altogether, and simply providing an opaque reference type for them to call your APIs with. One way to do this would be to define a fake structure, like struct GameObjectRef {};, and pass the user back a GameObjectRef*, casted from whatever pointer your system actually uses. This allows the user to write strongly typed code, so they can't accidentally provide the wrong pointer type to your functions, as they can with void*.
How pointers (and pointers-to-pointers) work:
Imagine you are asking me where your aunt lives. Then, I hand you a piece of paper with an address to go to. That piece of paper is a pointer to a house.
Now, take that piece of paper with the address, take a photo of it with your digital camera, and place the image onto your personal wiki site.
Now, if your sister calls, asking for your aunt's address, just tell her to look it up on your wiki. If she asks for the URL, write it on a piece of paper for her. This second piece of paper is a pointer to a pointer to a house.
You can see how an address isn't the same as the real thing. Just because someone has your website address doesn't mean they know your aunt's address. And just because they have your aunt's address doesn't mean they're knocking on her door. The same is true for pointers to objects.
You can also see how you can make copies of addresses (pointers), but that doesn't make a copy of the underlying object. When you take a photo of your aunt's address, your aunt doesn't get a shiny new house.
And you can see how dereferencing a pointer will lead you back to the original object. If you to go the wiki site, you get your aunt's address. If you drive to that address, you can leave a package on her doorstep.
Note that these aren't perfect metaphors, but they are close enough to be somewhat descriptive. Real pointers-to-pointers are a lot cleaner than those examples. They describe only two things - the type of the final object (say, GameObject), and the number of levels of indirection (say, GameObject** - two levels).
I think its not a double pointer, but a pointer to pointer, and yes if you want to get void* you must return *g_pGameRules.
The think is, that the pointers is like levels. You must show which level you want to get.
A pointer to a pointer is useful if you want have the pointer change (to a larger block of memory if you run out, for example), but keep a common reference to the item, wherever it moves.
If you are not going to be reallocating or moving the block pointed to, then dereferencinig like you have in your getter is fine. I haven't looked at the library you are using, but one thing to consider is that it may have reference counting when you get an instance in order to ensure the object isn't changed after you get the pointer.
So, what I would recommend is that you look to see if the library has any "Factory" functions or "instance" creating functions and use those.
-Dan8080

How to make a void** point to a function?

I have code that looks like this:
extern "C" __declspec(dllexport) myInterface(int id, void** pFunction)
{
...
}
I need to make the void** pFunction argument point to a function so that the caller can use this function via the pFunction pointer. This function gets called through a DLL, I don't want to do it this way but for a lot of reasons I have no choice. I know that COM is made for this but I can not use it, the reasons come down to management.
At this point I have no idea how to do this, everything I have tried to do gives me cast problems. Do anyone have any idea how I can do this? I can post more if this is unclear.
Thanks.
If you are looking at the implementation of 'myInterface', then you might be wanting:
switch (id)
{
case FUNC_1:
*pFunction = (void *)first_function;
break;
...
}
If you are trying to call the function and pass in a pointer to function, then:
void *vp = (void *)the_function_to_pass;
myInterface(1, &vp);
If you have something else in mind, you need to specify what.
(Note that strictly, C does not guarantee that function pointers can be assigned to object pointers and vice versa. However, POSIX does make that guarantee for you. I believe similar comments apply to C++.)
As Jonathan Leffler and David Thornley mentioned, you aren't guaranteed that a function pointer can be converted to void* and back. A portable workaround would be to package the function pointer into a struct and to pass a pointer to that.
(Be aware that void** itself might have its own issues. You can avoid this too.)
For example:
typedef int (*SomeFuncType)(int);
struct FuncWrapper
{
SomeFuncType func;
void* output;
};
...
FuncWrapper funcWrapper;
funcWrapper.func = ...;
myInterface(id, &funcWrapper);
and then myInterface could be implemented as:
void myInterface(int id, FuncWrapper* funcWrapper)
{
funcWrapper->func(...);
funcWrapper->output = ...;
}
This is not something that can be done in standard C or C++. There is no guarantee that a function pointer can fit into a void pointer (C++ member function pointers typically can't). In other words, if you can't change the function signature, you can't do what you want in standard C or C++, and there's no guarantee you can do it at all.
Therefore, any solution would be a platform-specific one. You don't specify a platform directly in question or tag, but my guess would be Visual C++ from other things.
Please specify your platform specifically, and anything useful about the function pointer you want to pass.
It's tricksy, but I've had good luck with code like so:
*reinterpret_cast<void**>( &(PVOID&)( DetourFunc ) ) = (PVOID) 0x00FFFF00;
The concept, as I understand it, is you're referencing a reference, reinterpreting the reference, then dereferencing it. Bit confusing, but I can verify it works. You can also put an address on the right side (&func) and it'll work. Calling DetourFunc, using the form:
(DetourFunc)(param, param)
will call the original address or function.
Edit: This works, but it seems like a pretty heavy abuse of the language. It does work, though, and has been recommended in a few other questions here.
I want to thank everyone for help. Here is how I get it to work at least in part. Basically the wrapper idea works.
struct myProj
{
virtual HRESULT __stdcall myMethod(unsigned short* & myname);
};
HRESULT __stdcall myMethod(unsigned short* & myname)
{
myname = L"myname";
return(1);
}
struct myProj xProject;
To call it:
extern "C" HRESULT __declspec(dllexport) fInterface(UINT id, LPVOID * pObj)
{
switch(id)
{
case FVI_ID:
*pObj = &xProject;
break;
}
}
This does call the correct function, but it still has it's problems. The third party DLL uses CStrings and I suspect they are giving my other problems as well as some trace functions they contain.
I believe my real solution is I can't fake out the com, that we need to realize the DLL's can not be used in our project.
Thanks everyone.

Pointer object in C++

I have a very simple class that looks as follows:
class CHeader
{
public:
CHeader();
~CHeader();
void SetCommand( const unsigned char cmd );
void SetFlag( const unsigned char flag );
public:
unsigned char iHeader[32];
};
void CHeader::SetCommand( const unsigned char cmd )
{
iHeader[0] = cmd;
}
void CHeader::SetFlag( const unsigned char flag )
{
iHeader[1] = flag;
}
Then, I have a method which takes a pointer to CHeader as input and looks
as follows:
void updateHeader(CHeader *Hdr)
{
unsigned char cmd = 'A';
unsigned char flag = 'B';
Hdr->SetCommand(cmd);
Hdr->SetFlag(flag);
...
}
Basically, this method simply sets some array values to a certain value.
Afterwards, I create then a pointer to an object of class CHeader and pass it to
the updateHeader function:
CHeader* hdr = new CHeader();
updateHeader(hdr);
In doing this, the program crashes as soon as it executes the Hdr->SetCommand(cmd)
line. Anyone sees the problem, any input would be really appreciated
When you run into a crash, act like a crime investigator: investigate the crime scene.
what is the information you get from your environment (access violation? any debug messages? what does the memory at *Hdr look like? ...)
Is the passed-in Hdr pointer valid?
Then use logical deduction, e.g.:
the dereferencing of Hdr causes an access violation
=> passed in Hdr points to invalid memory
=> either memory wasn't valid to start with (wrong pointer passed in), or memory was invalidated (object was deleted before passing in the pointer, or someone painted over the memory)
...
It's probably SEGFAULTing. Check the pointers.
After
your adding some source code
your comment that the thing runs on another machine
the fact that you use the term 'flag' and 'cmd' and some very small datatypes
making me assume the target machine is quite limited in capacity, I suggest testing the result of the new CHeader for validity: if the system runs out of resources, the resulting pointer will not refer to valid memory.
There is nothing wrong with the code you've provided.
Are you sure the pointer you've created is the same same address once you enter the 'updateHeader' function? Just to be sure, after new() note the address, fill the memory, sizeof(CHeader), with something you know is unique like 0XDEAD, then trace into the updateHeader function, making sure everything is equal.
Other than that, I wonder if it is an alignment issues. I know you're using 8 bit values, but try changing your array to unsigned ints or longs and see if you get the same issue. What architecture are you running this on?
Your code looks fine. The only potential issue I can see is that you have declared a CHeader constructor and destructor in your class, but do not show the implementation of either. I guess you have just omitted to show these, else the linker should have complained (if I duplicate this project in VC++6 it comes up with an 'unresolved external' error for the constructor. It should also have shown the same error for the destructor if you had a... delete hdr; ...statement in your code).
But it is actually not necessary to have an implementation for every method declared in a class unless the methods are actually going to get called (any unimplemented methods are simply ignored by the compiler/linker if never called). Of course, in the case of an object one of the constructor(s) has to be called when the object is instantiated - which is the reason the compiler will create a default constructor for you if you omit to add any constructors to your class. But it will be a serious error for your compiler to compile/link the above code without the implementation of your declared constructor, so I will really be surprised if this is the reason for your problem.
But the symptoms you describe definitely sounds like the 'hdr' pointer you are passing to the updateHeader function is invalid. The reason being that the 1st time you are dereferencing this pointer after the updateHeader function call is in the... Hdr->SetCommand(cmd); ...call (which you say crashes).
I can only think of 2 possible scenarios for this invalid pointer:
a.) You have some problem with your heap and the allocation of memory with the 'new' operator failed on creation of the 'hdr' object. Maybe you have insufficient heap space. On some embedded environments you may also need to provide 'custom' versions of the 'new' and 'delete' operator. The easiest way to check this (and you should always do) is to check the validity of the pointer after the allocation:
CHeader* hdr = new CHeader();
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
The normal behaviour when 'new' fails should actually be to throw an exception - so the following code will cater for that as well:
try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}
b.) You are using some older (possibly 16 bit and/or embedded) environment, where you may need to use a FAR pointer (which includes the SEGMENT address) for objects created on the heap.
I suspect that you will need to provide more details of your environment plus compiler to get any useful feedback on this problem.