Offsetof macro with C++/CLI - c++-cli

The offsetof macro seems not to work under C++/CLI.
This works fine in unmanaged C++, but throws "error C2275: 'Entity' :illegal use of this type as an expression" error in CLI.
struct Property{
char* label;
PropertyTypes type;
unsigned int member_offset;
unsigned int position;
unsigned char bit_offset;
};
struct Entity{
...
bool transparent;
...
};
Property property = {"Transparent",
TYPE_BOOL,
offsetof(Entity, transparent),
0,
0}; // C2275 HERE
Does CLI have some replacement?

My guess would be that the compiler message boils down to: "offsetof" is not a known macro and if it was a function its parameters must not contain a typename.
Edit: As somebody pointed out in the comments, offsetof is actually part of the std lib. So what's missing is probably just
#include <cstddef>
Alternatively, you can use this macro implementation (taken from Win32/MFC headers):
#ifdef _WIN64
#define OFFSET_OF( s, m )\
(size_t)((ptrdiff_t)&reinterpret_cast<const volatile char&>((((s*)0)->m)) )
#else
#define OFFSET_OF( s, m )\
(size_t)&reinterpret_cast<const volatile char&>((((s*)0)->m))
#endif

Standard C++ already has an alternative; &Entity::transparent. You'll probably want to use templates when redesigning the Propery class. The type of a pointer-to-member is non-trivial.

You will need to provide the type of the object you are assigning to. Looks like there is some type-mismatch for the member in question.
See this for sample usage.

Just a shot in the dark and without a chance to double-check this - should
offsetof(Entity, transparent),
perhaps rather read
offsetof( struct Entity, transparent ),
???

Related

How to use `git_note` from libgit2?

I've got code (where commit_id is already set) like:
git_note* note;
git_note_read(&note, repo, "refs/notes/label", &commit_oid);
printf("%s\n", note->message);
git_note_free(note);
It doesn't compile, complaining:
.../importer_test.cc:103:22: error: member access into incomplete type 'git_note'
printf("%s\n", note->message);
^
.../include/git2/types.h:160:16: note: forward declaration of 'git_note'
typedef struct git_note git_note;
If I just copy/paste from src/notes.h into this file:
struct git_note {
git_oid id;
git_signature *author;
git_signature *committer;
char *message;
};
It compiles and runs correctly. But surely that's not the right solution?
git_note is an opaque type. You're not meant to access members of the data directly. You should be using the accessor functions to read from it. In your case, you would want to use git_note_message() to get the message.

Why doesn't Clion recognise WxPuts?

The wxPuts method used in this tutorial (http://zetcode.com/gui/wxwidgets/helperclasses/) doesn't work. Was it changed and the class is no longer available?
I tried searching online for some documentation about wxPuts and wxPrintf, but can't find anything relevant in the helper files in the wxWidg site.
#include <wx/textfile.h>
int main(int argc, char **argv)
{
wxTextFile file(wxT("test.c"));
file.Open();
wxPrintf(wxT("Number of lines: %d\n"), file.GetLineCount());
wxPrintf(wxT("First line: %s\n"), file.GetFirstLine().c_str());
wxPrintf(wxT("Last line: %s\n"), file.GetLastLine().c_str());
wxPuts(wxT("-------------------------------------"));
wxString s;
for ( s = file.GetFirstLine(); !file.Eof();
s = file.GetNextLine() )
{
wxPuts(s);
}
file.Close();
}
wxWidgets provides wrappers for all standard CRT functions working with strings in order to allow calling them with wxString or wchar_t (wide) strings. These wrappers are not documented because it doesn't make much sense to re-document the standard functions, but basically for any foo(const char* s) in the standard library, you have wxFoo(const wxString& s) declared in wx/crt.h header. You have to include this header to get these declarations, however.
Also note that most of wxWidgets functionality can't be used before the library is initialized.
TL;DR: you're missing #include <wx/crt.h>.

#define macro redefined

Can you help me avoid this warning: 'kFontFromFontSize' macro redefined
in Gameconfig.h
#ifndef __GAME_CONFIG_H
#define __GAME_CONFIG_H
//
// Supported Autorotations:
// None,
// UIViewController,
// CCDirector
//
#define kFontFromiPaoneToiPad 2.1
#define kFontFromFontSize 2*kFontFromiPaoneToiPad
Your defines seems to work fine when I test using Visual Studio. Are you sure you are not defining these some other place as well? Perhaps your compiler treats it differently. In that case, you can use const globals instead:
const float kFontFromiPaoneToiPad = 2.1;
const float kFontFromFontSize = 2 * kFontFromiPaoneToiPad;
BTW, it is considered a good practice to use parenthesis around compound expressions in #define to avoid any potential problems when it is substituted in your code.

How to Marcshal a COM callback in C++/CLI

We have an out of process COM application that was written in C++ that implements are networking protocol. When a packet of data is received a callback is invoked into the application that registered for the packet.
The callback interface is defined as such:
[helpstring("method MessageHandler")] HRESULT MessageHandler([in,size_is(nSize)] char * szBuf, int nSize, DWORD dwTransCode, DWORD dwSenderID, BSTR bstrFromIP);
Using this in C++ has not been an issue. We now have a case where we have a C++/CLI application that needs to receive callbacks. After hacking away until the compiler was happy, I arrived at the following implementation:
ref class MessageHandlerClass : public MessageRouterCallback
{
public:
virtual void MessageHandler(signed char %buffer, int size, unsigned int msgId, unsigned int fromId, System::String^ fromIp)
{
switch (msgId)
{
case MaintenanceMsgs::maintenance_event_message::ID:
{
SomeStructure msg;
myHandler->HandleMaintenanceEvent(&msg);
}
}
}
This is my first foray into C++/CLI.
First Question: What they heck does '%' mean in 'signed char %buffer'?
Second Question: I can place a breakpoint and see that the callback is getting called. I can look at the 'buffer' argument in the memory debugger and it contains the data I expect. I have been VERY unsuccessful at pulling that data out and placing it into the variable 'msg'. I know I can't do a cast like in C++, but every example I've been tried (Mostly InteropServices::Marshal and some pin_ptr stuff) doesn't seem to get me anywhere.
SomeStructure is declared in a header file and is included by both the C++ and the C++/CLI application. SomeStructure contains 2 unsigned shorts followed by three character arrays.
Any direction on where to go from here would be greatly appreciated.
Ok. It just 'clicked'... So I'll answer my own question here.
First Question: What they heck does '%' mean in 'signed char %buffer'?
The '%' just means its 'tracked' and will be garbage collected, or at least that's what I think it means :)
Second Question: How to marshal.
First I had to get to the 'internal pointer' and C++/CLI provides the & operator for that. Then I was able to simply memcpy the data over.
pin_ptr<signed char> p = &buffer;
MaintenanceMsgs::maintenance_event_message msg;
memcpy((void*)&msg, (void*)p, sizeof(msg));
myHandler->HandleMaintenanceEvent(&msg);
Is this safe?

integer constant does 'not reduce to an integer'

I use this code to set my constants
// Constants.h
extern NSInteger const KNameIndex;
// Constants.m
NSInteger const KNameIndex = 0;
And in a switch statement within a file that imports the Constant.h file I have this:
switch (self.sectionFromParentTable) {
case KNameIndex:
self.types = self.facilityTypes;
break;
...
I get error at compile that read this: "error:case label does not reduce to an integer constant"
Any ideas what might be messed up?
For C/C++ and Objective-C must the case statement have fixed values - "reduced to an integer (read value)" at compile time
Your constants is not a real "constant" because it is a variable and I imagine it can be changed through a pointer - ie &KNameIndex
Usually one defines constants as enum
enum {
KNameIndex = 0,
kAnotherConstant = 42
};
If you would use C++, or Objective-C++ (with .mm as file extension) you could use a const statement as
const int KNameIndex = 0;
You can use
#define KNameIndex 0
...
switch (self.sectionFromParentTable) {
case KNameIndex:
self.types = self.facilityTypes;
break;
...
and it should work.
Just had the same problem and I decided to go with #define rather than enum. Works for me™ ;-)
This is a stab in the dark because I haven't used Cocoa / ObjC in a long time now, but is the member variable sectionFromParentTable not of int type?
I have not worked with Objective C, but I'd try chucking the 'extern'. At least if this were C++, the Constants.m file would not be part of the compilation unit of Other.m, so the value of KNameIndex would be unknown to the compiler. Which would explain the error; an unknowable value can't be a constant.
Does putting the definition, not just the declaration, in the Constants.h file help?
I think you are stuck with using a const int instead of a const NSInteger as switch only works with built in integral types. (not sure about your syntax with const flipped around after the type).
Take a look at the related question: Objective-C switch using objects?