Compilation fails when importing DTCoreText in ObjC++ file - objective-c

I've been trying to import DTCoreText.h in a class with both Objective-C and C++ code, but it results in the following cryptic compilation errors:
The code doesn't have syntax errors and works correctly when I use it in classes written exclusively in Objective-C, but if I change their extension to .mm the compilation fails. This indicates that is something related to the C++ compiler, but I'm not sure exactly what.
Does anyone have a clue? Thanks.

This was happening due to the fact that some method signatures had parameters with the name class which is a reserved keyword in C++ and eventually led to the compilation errors I've listed above.
Changing the parameters name fixed it.

Related

How to handle 'Object': ambiguous symbol in Visual Studio

I am creating a C++/CLI wrapper for native C code that has it's own Object typedef and am receiving the C2872 'Object': ambiguous symbol error when linking. The compiler output is:
1>C:\src\OS_kernel.h(27): error C2872: 'Object': ambiguous symbol
1>C:\src\OS_types.h(261): note: could be 'ObjectStruct *Object'
1>C:\src\OS_kernel.h(27): note: or 'System::Object'
It may be worth mentioning that I am mocking this native C code for the purposes of the C++/CLI wrapper; not sure if that opens up a potential solution that would otherwise not be available if no source code was available. I'm guessing there is a way to specify which definition I want the code to use, but I don't know how to specify that. Is that possible? I want to specify it to use the ObjectStruct *Object.
It would be great if I didn't have to modify the mock code since it could potentially be hundreds or thousands of individual places.
As an aside, I am also receiving this error for other types the native library is using, such as Buffer and Boolean.
OK, since you're getting the error in OS_kernel.h, I'm guessing that's part of the C code you're wrapping.
Obviously, one possible solution is to treat the name Object as a reserved word, and edit your C code to not use it. One could argue that this is the most correct solution, but it may not be possible to do that.
Depending on how you're referencing the C code, it may be reasonable to compile it as C++, and stick it entirely within a namespace. That way, when the C code (now C++ code) uses Object it will see the typedef within its namespace, and you'll have the option to reference either namespace in your code.
The fact that you're getting this error from your library's header file indicates to me that you've got a using namespace System; directive, and that the #include of your library's header files comes after that using directive. Consider removing the using namespace System;, or at least moving it after the #include. This way, you won't get that error in the library's headers, you'll just have to deal with it in your code.

libgit2 GIT_BUF_INIT undeclared; where should it be declared?

I'm running through the libgit2 sample code for getting the content of blobs, and I've hit a problem with the line:
git_buf filtered_content = GIT_BUF_INIT;
I get error C2065: 'GIT_BUF_INIT': undeclared identifier, which makes sense, because I can't find this defined in any of the included header files. As nobody seems to have asked this question before I get the strong feeling I'm missing something obvious. Any ideas on what I need to do to use GIT_BUF_INIT?
That's declared inside the library because it references an internal buffer. You should zero the structure as usual for C.
If the examples contain GIT_BUF_INIT they were probably extracted from the tests and we missed that it's not available outside.

C++/CLI error C1189 when I Include marshal library

I've got a application that is communicating with a PLC.
I have some libraries included for the communication but when I add marshal:
#include <msclr\marshal_cppstd.h>
it gives me the following error:
C1189: #error: The C++ Standard Library forbids macroizing keywords. Enable warning C4005 to find the forbidden macros.
C4005: 'inline': macro redefinition
this C4005 warning shows in
xkeycheck.h line 203 which contains:
#define inline EMIT WARNING C4005
and I get a ton more of errors(1800+).
So what does this error mean?
inline is a C++ keyword which this #define is re-defining. It's warning you that it's pretty risky to change the meaning of inline.
msclr\marshal_cppstd.h has functions marked with inline so this is probably the first occurrence of code using the re-defined inline definition and it's realizing that it is probably not what you're expecting.
I would question why xkeycheck.h is redefining inline -- perhaps inlining is not allowed with their library? Perhaps you need to push/pop the definition of inline around your include or #undef inline before your include?
Update: Did more research, I was assuming xkeycheck was from the PLC code. It's not. So, xkeycheck is set up to report this error if it sees that you've redefine any of the C++ keywords. inline in this case. As I said above, marshal_cppstd.h actually uses inline so that's the first sign of trouble and it's emitting the warning. So.... my advice is to search all your code and find out where you or a header you include has #define'd inline to something else.
I would put the cursor on inline and press F12 to go to the definition.

Can simply importing a header ever lead to run-time issues?

I realize that doing this can lead to compile errors. But is an import always safe if no (new) compile errors or warnings arise? If I use an import statement (e.g. to remove duplicate protocol definition warning), could doing so, on it's own, ever change the run-time behavior? What checks (if any) are necessary to ensure invariability of operation after a new header import?
Yes, importing a header can lead to run-time issues.
For example, you may get a warning that a selector is unknown so the compiler is making assumptions about its signature. If you fix that warning by importing the relevant header, then that changes the code the compiler is emitting. Generally, it would change the code from broken to correct, but that nevertheless results in a run-time change.
If you use #import, then the header could define preprocessor macros that radically alter the subsequent code. For example, it could #define setNeedsDisplay setHidden or something.
The only way I can think of to verify that importing the header didn't alter the generated code is to examine the generated code and compare before and after. You can ask Xcode or clang to produce assembly from the compilation. You could also use otool -tV to disassemble the binaries (although that wouldn't show changes in, say, static data like strings).

ICollectionPtr COM

I have an issue that ive been batteling with for a day or so now and im wondering if anyone might be able to help:
Im am trying to use the ActiveMQ-NMS to dequeue messages via COM in a C++ application. I have managed to build the source and override the 'ComVisible' flag in order to export all the types in the assembly via RegAsm (i did receive warnings about this and the 'Atomic' class but i dont think this is the issue i am facing at the moment).
As part of the RegAsm i have generated a .tlb file that i use in a #import in the C++ client. However, i then receive various errors whilst compiling. Things like:
error C2146: syntax error : missing ';' before identifier 'Keys'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Essentially, it looks like things like the ICollectionPtr (and various others) are unavailable. Can anyone help me as to resolving these issues? Essentially im looking to register the .net ActiveMQ-NMS assembly as a COM compliant component and then use it from C++...
Unless there's some other reason to use COM and NMS, why not just use the ActiveMQ-CPP client? Then you can avoid all the complexity of COM. ActiveMQ-CPP is located here: