Using directive to specify class alias in C++/CLI - c++-cli

In C#, there are three types of using directives:
using System; // Specify Namespace
using Diag = System.Diagnostics; // Specify Namespace Alias
using DBG = System.Diagnostics.Debug; // Specify Class Alias
In C++/CLI, I know the equivalents to the first two:
using namespace System;
namespace Diag = System::Diagnostics;
Is there any way to do the third one in C++/CLI?
Doing namespace DBG = System::Diagnostics::Debug; gives error C2879: 'System::Diagnostics::Debug' : only an existing namespace can be given an alternative name by a namespace alias definition
The only alterntive I've come up with is #define DBG System::Diagnostics::Debug, but I'd prefer a proper using directive, if available.

A C++ typedef will do the trick here.
typedef System::Diagnostics::Debug DBG;

Related

How to use existing UHD function calls in a custom OOT module in Gnu Radio

I am making a custom OOT module called test3 in GNU Radio which needs to use some uhd functions.
For example, I need to call the uhd::set_thread_priority_safe() function, so I import the thread.hpp file:
#include <uhd/utils/thread.hpp>
Since the function call is in the uhd namespace, so I try to use the namespace to call the function:
namespace gr {
namespace test3 {
using namespace uhd;
.
.
.
int get_time_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
uhd::set_thread_priority_safe();
return 0;
}
}
But doing this does not work, and I get the following error:
AttributeError: module 'test3' has no attribute 'get_time'
But when I remove the uhd function call, the error goes away.
How can I solve this problem?
I solved the issue by the following steps.
In gr-module/CMakeLists.txt, I added 'find_package(UHD)' in the 'find gnuradio build dependencies' section.
In gr-module/lib/CMakeLists.txt, I updated the target link libraries command to 'target_link_libraries(gnuradio-module gnuradio::gnuradio-runtime UHD::UHD)'.
After running cmake and make commands after the above changes, the issue was resolved.
Do not use using namespace uhd;! You're not even making use of that imported namespace, so it's totally useless, and it risks that you override things within your scope with elements from the uhd namespace. As you currently do, access to elements from that namespace works simply by specifying the namespace when accessing, as in uhd::set_thread_priority_safe.
Rule of thumb: using namespace xyz; is very rarely a good idea. Avoid it.
Whether or not that is the problem here is impossible to tell.

Attempting to print SerialPort inputs to the console

First my code:
#include <iostream>
#include <thread>
#using <System.dll>
using namespace System;
using namespace System::IO::Ports;
using namespace System::Threading;
int main()
{
SerialPort^ mySerialPort = gcnew SerialPort("COM5");
mySerialPort->BaudRate = 9600;
mySerialPort->Parity = Parity::None;
mySerialPort->StopBits = StopBits::One;
mySerialPort->DataBits = 8;
mySerialPort->Handshake = Handshake::None;
mySerialPort->RtsEnable = true;
while (1)
{
Console::WriteLine(Console::ReadLine());
}
}
The idea was to read from the SerialPort and write to the console. Source
Originally I was going to use:
std::cout << Console::ReadLine() << '\n';
However, that had an error (ReadLine outputs String^ not String, I don't know the difference) and I was hoping for something to compile.
With the above code I received the error:
two-phase name lookup is not supported for C++/CLI ... use /Zc:twoPhase-
The error recommends I use /Zc:twoPhase- which is a compiler option. So I enabled it and got the error:
Element has an invalid value of "Yes(/permissive-) /Zc:twoPhase-"
I'm not quite sure how to proceed from here.
Apologies I'm a beginner and I dove way over my head. Any help would be appreciated!
Note: I included thread, I know this code doesn't use it, but I plan on using it later.
Judging by the "Element has an invalid value of "Yes(/permissive-) /Zc:twoPhase-"" you've put this compiler option where it does not belong. Make sure you know where it should go. E.g. Why do I have warning "C4199 two-phase name lookup is not supported for C++/CLI, C++/CX, or openmp"?
There is no solution. I got an "cannot open file 'MSCOREE.lib'" error. It appears that file no longer exists in Windows and I didn't know how to get ahold of it. So I used the Visual Studio Windows Form App.
Edit: eXCore's comment about the .NET framework solved it.

'mutex': is not a member of 'std', error when using Armadillo in CLR

I am using Armadillo in c++ CLR, when I include armadillo in my solution and building it, I get this error:
missing type specifier - int assumed. Note: C++ does not support default-int
'mutex': is not a member of 'std'
'cache-mutex':unknown override specifier
Here is my code and I have not written anything yet:
#include "pch.h"
#include <include/armadillo>
using namespace System;
int main(array<System::String ^> ^args)
{
}
How can I solve this issue?
Define a macro named ARMA_DONT_USE_STD_MUTEX before #includeing the armadillo header. Example:
#define ARMA_DONT_USE_STD_MUTEX
#include <armadillo>
The documentation says:
ARMA_DONT_USE_STD_MUTEX
Disable use of std::mutex; applicable if your compiler and/or environment doesn't support std::mutex

How to convert from C# ref type to CLI\C++ ^% type

I am writing an application in Managed C++ (CLI\C++). In which I am using a library (.dll file) which is written in C#.
In a file I am encountering a problem.
I am implementing functions of an interface which is written in the library.
The declaration of a function in the library is as given below:
COMWORKSPACELib.IWorkspaceEvents.WorkspaceMessage(int, string, COMWORKSPACELib.EnumNotificationCode, COMWORKSPACELib.EnumNotificationType, string, ref COMWORKSPACELib.EnumNotificationReply);
When I write the same code in CLI\C++ the declaration is like:
WorkspaceMessage(int workspaceToken, String ^description, EnumNotificationCode ^code, EnumNotificationType ^type, String ^source, EnumNotificationReply ^%action);
Here, the compiler is giving me error that the “class must provide an implementation for the interface method”. Because the parameters passed in both function declarations are syntactically different.
Is there any alternative way to match the library declaration?
If I remove the “^’ & ‘%’ to match the library declaration then it gives further errors in the code.
Are EnumNotifcationCode, EnumNotificationType, and EnumNotficationReply all enums? That is, are they value types? If so, then it should be declared as follows:
WorkspaceMessage(int workspaceToken,
String^ description,
EnumNotificationCode code,
EnumNotificationType type,
String^ source,
EnumNotificationReply% action);

HashMap : Dealing with Managed objects C++

I guess it's kind of a stupid question but here is my problem :
I want to have a hash_map<int, Object^> as an attribute of my object BigObject, which is written in managed C++.
So I have to declare a pointer, hash_map<int, Object^>* hash because I cannot declare explicitely native object in managed code.
How can I insert an object ? the hash_map[] won't work with a pointer, and I cannot make insert work (I cannot use a std::pair<int, Object^> because Object is managed...
Thanks a lot
You should declare your hashmap as hash_map<int, gcroot<Object^> >. You will need to #include <vcclr.h>
See also msdn
edit: added code sample
#include <iostream>
#include <vcclr.h>
#include <hash_map>
using namespace std;
using namespace stdext;
using namespace System;
int main()
{
hash_map<int, gcroot<Object^> > hash;
hash.insert( make_pair<int, gcroot<Object^> >( 5,
gcnew String("hello world") ) );
return 0;
}
If you're working in .NET, why not use one of the .NET collections? They are directly usable in C++/CLI, and can also be shared with other .NET languages, which a std::hash_map cannot. And they play nicely with the garbage collector.
.NET provides several hashtable implementations, including 'System.Collections.HashTable' and System.Collections.Generic.Dictionary.
In your case, a Dictionary<int, Object^>^ would be appropriate.
hash_map <double,gcroot<siteNEVObjectdic^>> d;
d.insert(make_pair<double,gcroot<siteNEVObjectdic^>>(PN2,gcnew siteNEVObjectdic(Lat1,Long1,Lat2,Long2,Lat3,Long3)));
this worked as a charm.