How do I use ConditionalAttribute in C++-CLI? - c++

I have a C++-CLI ref class that exposes a profiling infrastructure implemented in C++.
In C++ I have the preprocessor directive PROFILING_ENABLED to determine whether the intrusive profiling functions are in the code or not.
When exposing these to managed code, I thought that using the managed ConditionalAttribute would be appropriate. But I struggle with the syntax.
Here is my attempt:
#ifdef PROFILING_ENABLED
// c++ macros are defined and active on the project level, I would like the
// conditional attribute to be active as well.
#define MANAGED_PROFILING_ENABLED
// how do I define the managed conditional "MANAGED_PROFILING_ENABLED" in C++-CLI?
#endif
public ref class Profiler
{
public:
[ConditionalAttribute("MANAGED_PROFILING_ENABLED")] // this compile but always inactive
static void PushRange(System::String ^ name, Color color);
[ConditionalAttribute("MANAGED_PROFILING_ENABLED")]
static void PopRange();
};
I would like to achieve the following:
If the native c++ preprocessor directive is active, the managed ConditionalAttribute should be active as well.
If on the other hand the native c++ preprocessor directive is inactive, the managed ConditionalAttribute should be inactive.

The below standards document is pretty old. But assume that, may be still valid.
https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-372.pdf
Go to section 29.4.3 (You can find below content about conditional attributes in c++/CLI).
C++/CLI does not provide this ability; although attributes of this
type are accepted, they have no affect on code generation or
execution.

Related

When is QT_NO_CONTEXTMENU defined?

In the Qt documentation on menus, they show how to override the Context Menu for a widget. They use the macro QT_NO_CONTEXTMENU, but they don't make any comments in the text about this macro, why it's there, or who uses it:
#ifndef QT_NO_CONTEXTMENU
void contextMenuEvent(QContextMenuEvent *event) override;
#endif // QT_NO_CONTEXTMENU
When is QT_NO_CONTEXTMENU defined by Qt?
I could see Qt defining this macro for you on systems that don't support context menus, for example. Since QAbstractScrollAreas declaration of contextMenuEvent is wrapped in this same way, I know I must use the macro as well to be safe, otherwise I risk using override on a non-existent function that would never get called. But I want to know what would cause this macro to be defined in the first place, since it seems very odd to me that this would be a macro in the first place, rather than a member variable of QAbstractScrollArea that can be set at any time.
This macro gets defined when the -no-feature-CONTEXTMENU option is set when configuring and building Qt from source, i.e. using the configure tool. You are correct that it's for systems that don't support context menus. These are usually embedded systems (e.g. touch-screen kiosk) that have limited resources so you don't want to bog them down with any extra modules, especially ones that won't be used anyway.

C++ Compile time check if a microcontroller pin is already initialized from other source file

Typically a microcontroller pin can be identified with with port number and pin number.Both are compile time constants.
A pin can have multiple functions,if used in a big project multiple source file can initialize same pin and break functionality implemented in other module.
I want to implement a compile time list which is initially empty and each time a pin is initialized it will check if the pin is already
present in that list, if its present it will give a static assert otherwise it will insert pin information in the list. List is not required at run time.
I don't have enough knowledge of meta programming, It would be great if someone can provide me direction to implement it.If there is already some library for this kind of purpose, please provide the links
What you want is not possible. C++ metaprogramming does not have a state, it's more akin to a functional language than declarative one. So you cannot have a mutable list. The only state can be introduced by creating new types, but there's no available syntax to check if a particular non-nested name is declared or defined.
Multiple source files (compilation units) are compiled independently so there's certainly no "global state" and that makes it more impossible.
Also, note that what you are doing is inherently run-time. The compiler has no tools to check if you are calling the initialization function twice. These calls might be hidden behind some run-time if-else decisions. And simply writing HAL_GPIO_Init(); no matter how many times in the whole program is not an error.
The simplest thing I can think of is creating a C++ singleton class that is responsible for communicating with pins. You can have a dedicated int init_GPIO method using error_codes or exceptions if they are enabled. Instead of static_assert you will have to rely on tests - that singleton works correctly and the return value of init_GPIO is not ignored.
If you really do not want to bother with singleton, this function template works too:
template<std::size_t GPIO, std::size_t port> int GPIO_init(GPIO_InitStruct& s){
static bool initialized=false;
if(initialized) return <already_called>;
initialized=true;
//Assuming that you want to propagate the return value.
return HAL_GPIO_Init(GPIO, port, s);// Replace with the correct call.
}
If you require thread-safe initialization then use:
template<std::size_t GPIO, std::size_t port> int GPIO_init(GPIO_InitStruct& s){
static std::once_flag initialized;
int ret_val = <already_called>;
auto call = [&](){ret_val = HAL_GPIO_Init(GPIO, port, s)};
std::call_once(initialized, call);
return ret_val;
}
Assuming that every driver or HAL has a header file, and there's a main.cpp which includes all those headers, then you can do this with the pre-processor.
Optionally, make a project-wide header "pintype.h" with an enum such as this:
// pintype.h
typedef enum
{
PIN_GPIO,
PIN_PWM,
PIN_ADC,
PIN_UART,
...
} pin_t;
Then for every header file, write a pre-processor check, for example:
// pwm.h, header of the pwm driver or HAL
#include "pintype.h"
#ifdef PIN9
#error Pin 9 already taken
#else
#define PIN9 PIN_PWM
#endif
The #error is strictly speaking not needed, because in case of conflicts the compiler will complain about multiple definitions in the same translation unit (that of main.cpp).
When the developer writing the driver gets an error message, they can go to the pre-processor definition of the pin and find out which other module in the project that has claimed it already, without digging inside the internal implementation of that driver.

Return argument in function parameter of C++

I am trying to understand a typedef but I am stuck with this Code:
typedef _Return_type_success_(return == DUPL_RETURN_SUCCESS) enum
{
DUPL_RETURN_SUCCESS = 0,
DUPL_RETURN_ERROR_EXPECTED = 1,
DUPL_RETURN_ERROR_UNEXPECTED = 2
}DUPL_RETURN;
My question is:
1) What is the Return argument doing in parameter of a function
2) we usually define typedef like this
typedef int foo;
I am unable to understand this above format.
I am a noobee to serious c++ programming, Thankyou for your time.
EDIT: I am trying to build this streaming app, so I need to retrieve frames as fast as possible, I came across a few articles that recommended DXGI way which is a fast solution. I am trying to understand how to use the windows desktop Duplication API. I found this code on official msdn website : here
_Return_type_success_ it is not part of the official c++ standard, but part of the Microsoft source code annotation language (which is proprietary addition to the c++ syntax):
Using SAL Annotations to Reduce C/C++ Code Defects
SAL is the Microsoft source code annotation language. By using source code annotations, you can make the intent behind your code explicit. These annotations also enable automated static analysis tools to analyze your code more accurately, with significantly fewer false positives and false negatives.
And _Return_type_success_ itself is described in Success/Failure Annotations
_Return_type_success_(expr): May be applied to a typedef. Indicates that all functions that return that type and do not explicitly have _Success_ are annotated as if they had _Success_(expr). _Return_type_success_ cannot be used on a function or a function pointer typedef.
_Return_type_success_ is most certainly just a macro defined as #define _Return_type_success_(arg) so that it is completely removed while compiling. This is at least the case for the sal.h (no_sal2.h ) header used in some azure code.

How to create a DLL, which accepts strings from MT4 and returns back string type?

I am trying for two weeks to create a DLL to which I can pass strings and get back strings. But still no success.
I tried this on Dev-C++(TDM-GCC 4.9.2) and visual studio community 2015. I searched a lot about this and tried almost every sample code I found but I have no success.
I have to use this DLL with MetaTrader Terminal 4.
Here is a one sample code, which I used. This code compiles successfully but when I send a string to this, from MT4, I get an access violation error.
#ifndef MYLIB_HPP
#define MYLIB_HPP
#include <string>
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllimport)
#else
#define MYLIB_API __declspec(dllexport)
#endif
bool MYLIB_API test(const std::string& str);
#endif
bool MYLIB_API MyTest(const std::string& str)
{
return (str == "Hi There");
}
If you do share a C++ string between a DLL and another executable, both need to have been compiled with the same tool-chain. This is because std::string is defined in header only. So, if the DLL and executable use different string headers, they may well be binary incompatible.
If you want to make sure that things do work with different tool-chains, stick to NULL terminated C strings.
You have just experienced one of the MQL4 tricks,the MQL4 string is not a string but a struct thus #import on MQL4 side will make MT4 to inject that, not matching your DLL C-side expectations and the access-violation error is straightforward, as your C-side code tried to access the MQL4 territories...
First rule to design API/DLL: READ the documentation very carefully.
Yes, one may object, that the MQL4 doc is somewhat tricky to follow, but thus more double the Rule#1, read the documentation very, very, very carefully as some important design facts are noted almost hidden in some not very predictable chapters or somewhere in explanations of ENUM tables, compiler directives, pragma-s side-notes et al.
Second rule: design API/DLL interface so as to allow smooth integration
MQL4 has changed the rules somewhere about Build 670+. Good news is, the MetaQuotes has announced, that there will be no further investment on their side into MT4 further developlments, so the MT4-side of the DLL/API integration will hopefully stop from further creeping.
Given your statement, that you design the DLL/API, try to design future-proof specification -- use block of uchar[]-s instead of "interpretations"-sensitive string, pass both inputs and outputs by-reference and return just some form of int aReturnCODE = myDLL_FUNC( byRefParA, byRefParB, byRefRESULT ); and your efforts will result in clean code, better portability among 3rd party language-wrappers and will also minimise your further maintenance costs.
Most likely, your code and the one you're linking against have been compiled with a different ABI for std::string, i.e. the string used by the library has a different memory layout (and sizeof) than the one you're compiling with.
I once ran into this problem when linking against the hdf5 library and using gcc. In this case, the problem could be solved by reverting to a previous ABI, as explained here.
However, the problem also occurred with clang, when such a solution was not available. Thus, to make this all working I had to avoid using std::string in any calls to the library (hdf5 in my case) that was compiled with the different ABI, and instead make do with the hdf5 interface using const char*.

valuechange event similar functionality in c or c++

I'm implementing a global debug module ,a single module contains a struct to hold all global variables in C, and our code has both C and C++ modules. Is there a way if an existing variable is set somewhere, would also cause to update debug global variables in structure as well.
I was thinking of setter functions , but this requires modification in every module.Instead is there a way to replicate functionality like valuechangeevent in JSF with C or C++.
You can make the debug module contains all the pointers to the variables you are monitoring.
struct debug {
int * pointer_to_var_1;
};
struct debug __debug__;
__debug__.pointer_to_var_1 = &var_1;
Now suppose var_1 is changed somewhere, and you can directly see from __debug__ by accessing:
*(__debug__.pointer_to_var_1) //This is up to date
Otherwise, you will have to use a setter and change everything in the modules, or use an infinite loop or timer to monitor all the variables. There is no event registration for value change in C.
You might be able to do it with some pre-processor trickery:
#ifdef DEBUG
#define myvar global_debug_thingy->myvar
#else
int myvar;
#endif
I don't think that you can do accessor functions, or notifiers this way as it would need different code for reading and writing, and preprocessor can't do this.