I am trying to make a managed .dll in c++ that requires the support for multithreading. I am developing in visual Studio 2013, using platform toolset version v120. the reason I need this to be a managed assembly is because it is required to integrate the assembly in LabView.
following the steps in Creating and Using a Managed Assembly in VC++ 2010 gives good results. but I obviously need to implement something more complicated and when I include threading and write the following code:
#pragma once
#include <thread>
using namespace System;
using namespace std;
namespace MultiThread_module {
public ref class multiThreadingTest
{
public:
String^ GetVersion();
int someNumber;
private:
thread testThread;
};
}
I get following errors:
"thread" is not supported when compiling with /clr or /clr:pure.
a member of a managed class cannot be of a non-managed class type
error directive: ERROR: Concurrency Runtime is not supported when
compiling /clr.
error directive: is not supported when compiling with /clr or
/clr:pure.
A friend of mine says it is impossible to write multi-threaded code in Visual Studio without using external packages like boost. It kind of seemed unlikely since Multithreading has already been already there for C# and VB for a long time!
So, I would be happy if you could let me know what I am doing wrong OR if it is really hard to have a managed multithreaded .dll developed in c++?
You can use the managed thread library: System.Threading.Thread.
#pragma once
using namespace System;
using namespace std;
using namespace System::Threading;
namespace MultiThread_module {
public ref class multiThreadingTest
{
public:
String^ GetVersion();
int someNumber;
private:
Thread^ testThread;
};
}
If it's purely CLR then I suggest you use the example provided before. If you want to have the threading completely native and just use CLR to wrap it, I'd like to refer you to my answer at : using clr and std::thread
Might be an old question, but I looked into this same problem before. Since CLR does not allow you to include std::thead at
compile time, you could try to use it only at linking time. Normally
you could resolve this be forward declaring the class in your header
and including them only in your cpp files. However you can forward
declare your own classes in header files, but you can't for
classes in namespace std. According to the C++11 standard, 17.6.4.2.1:
The behavior of a C++ program is undefined if it adds declarations or
definitions to namespace std or to a namespace within namespace std
unless otherwise specified.
A workaround for this problem is to create a threading class that
inherits from std::thread that you can forward declare. The header
file for this class would look like:
#pragma once
#include <thread>
#include <utility>
namespace Threading
{
class Thread : std::thread
{
public:
template<class _Fn, class... _Args> Thread(_Fn fn, _Args... args) : std::thread(fn, std::forward<_Args...>(args...))
{
}
private:
};
}
In the header file that you would like to use the thread you can do
forward declare it like:
#pragma once
// Forward declare the thread class
namespace Threading { class Thread; }
class ExampleClass
{
public:
ExampleClass();
void ThreadMethod();
private:
Threading::Thread * _thread;
};
In your source file you can then use the theading class like:
#include "ExampleClass.h"
#include "Thread.h"
ExampleClass::ExampleClass() :
{
_thread = new Threading::Thread(&ExampleClass::ThreadMethod, this);
}
void ExampleClass::ThreadMethod()
{
}
Hope it might help anyone.
Related
I have a struct defined in Managed.h and I would like to be able to use it inside a different project, which is unmanaged C++ (let's call it Unmanaged.h).
I tried referencing the dll, a few different #includes, but I couldn't make it work. Is there a simple way to do this ?
For information : I am quite new to C++ programming (I do C# usually), and I use Visual Studio 2015.
It would be useful to see some code and the error message that you are seeing. But as a basic example:
CLR file containing the struct. Call it MyStruct.h:
using namespace System;
namespace ManagedNameSpace {
public value struct MyStruct {
void f() {
System::Console::WriteLine("test");
}
};
}
The unmanaged class includes the CLR struct and as an explicit example I have called the object in the constructor but you can easily move this to an implementation file (Remember to include the file in the header):
#include "MyStruct.h"
class UnManagedClass {
public:
explicit UnManagedClass() {
ManagedNameSpace::MyStruct clrObj;
clrObj.f();
std::cout << "This compiles fine";
}
};
Take note that certain CLR types require marshalling. For example String will need to be marshalled. Here is an example of converting a string to LPCWSTR
LPCWSTR lpcwStr = (LPCWSTR)(Marshal::StringToHGlobalUni(clrString)).ToPointer()
Preface
I'm trying to increase my C++ code robustness and, for quite some time, I have been plagued with the issue of namespace pollution.
Because using namespace::std; is a obvious bad practice, I have always explicitly declared my intentions when using data structures and functions from other namespaces, by using using std::array declarations inside the namespace where I implement my data structures.
But this can still be a problem. For example, if I have a namespace called products and, if I declare all of my products data structures inside the products namespace, namespace pollution will still occur, due to the increase of using std::XYZ declarations.
It can easily get to a point where, when using the Eclipse CDT indexer, I will see more standard types, functions and data structures inside my own namespaces, than the data types that I myself have implemented.
My Unsuccessful Solution
In order to achieve some contention, I decided to try the Boost Lib example and isolate the data structures implementation in their own namespace. Boost uses the detail namespace for this.
But now I have a bigger problem because of the C++ friendship mechanism and how data and functions are declared in namespaces.
The following code uses the c++ friendship mechanism in order to prevent the instantiation of ProductA by any other object except for the FactoryA objects. It also follows my attempt to isolate the namespace where ProductA is declared.
Product A Code
#ifndef PRODUCT_A_GUARD__
#define PRODUCT_A_GUARD__
namespace factories {
class FactoryA;
}
namespace products {
namespace productA_detail {
using std::uint32_t;
using std::size_t;
class ProductA {
friend class factories::FactoryA;
const uint32_t productID;
ProductA(const uint32_t& productID)
: productID{productID}
{}
public:
virtual
~ProductA() {}
};
}
using productA_detail::ProductA;
}
#endif //PRODUCT_A_GUARD__
Factory A Code
#ifndef FACTORY_A_GUARD__
#define FACTORY_A_GUARD__
#include <memory>
#include "productA.hpp"
namespace factories {
namespace FactoryA_detail {
using std::uint32_t;
using std::unique_ptr;
using products::ProductA;
class FactoryA {
uint32_t created_products {0};
public:
FactoryA() {}
unique_ptr<ProductA> Created_ProductA() {
return unique_ptr<ProductA>(new ProductA(created_products++));
}
virtual
~FactoryA() {}
};
}
using FactoryA_detail::FactoryA;
}
#endif //FACTORY_A_GUARD__
Main
#include <memory>
#include "factoryA.hpp"
#include "productA.hpp"
int main (){
using std::unique_ptr;
using factories::FactoryA;
using products::ProductA;
FactoryA factory;
unique_ptr<ProductA> product = factory.Created_ProductA();
return 0;
}
This code will not compile with GCC 6.2
The compiler will complain about FactoryA being already declared at the factories namespace
In file included from test.cpp:4:0:
factoryA.hpp: At global scope:
factoryA.hpp:29:26: error: ‘FactoryA’ is already declared in this scope
using FactoryA_detail::FactoryA;
Because of this issue, I'm unable to devise a helpful way to prevent a namespace pollution by the constant use of the using std::XYZ declarations and, still be able to make use of the C++ friendship mechanism to prevent misuse of some of my data structures.
Does anyone know a way to achieve my objective or, if it is possible to be achieved in the first place?
I have a problem with the compiling of code with the xlC_r compiler on AIX OS. I have attached my code below which is causing the problem. I have tried to compile the
code on MS Windows with microsoft compiler and also compiled it under Linux with gcc and everything worked fine. The compiler error which I get is following:
"...../ABC.h", line 12.22: 1540-0063 (S) The text "<" is unexpected.
I have searched the internet and I found some resources (link and link), I do not know how to integrate the solution into my code. One possible solution
would be to remove the shared_ptr and just have the pointer value, but I do not like to manage the deleting of pointer by myself. I would relly appreciate any help.
ABC.h
#ifndef ABC_H
#define ABC_H
#include <vector>
#include <memory>
template<class SR_TYPE, class SM_TYPE>
class ABC {
private:
std::shared_ptr<SR_TYPE> mpRV;
std::vector<SM_TYPE> mMsgs;
public:
ABC(void);
ABC(SR_TYPE* pReturnValue);
virtual ~ABC(void);
}; // ABC
template<class SR_TYPE, class SM_TYPE>
ABC<SR_TYPE, SM_TYPE>::ABC(void) {
}
template<class SR_TYPE, class SM_TYPE>
ABC<SR_TYPE, SM_TYPE>::ABC(SR_TYPE* pReturnValue) {
mpRV.reset(pReturnValue);
}
template<class SR_TYPE, class SM_TYPE>
ABC<SR_TYPE, SM_TYPE>::~ABC(void) {
}
#endif // ABC_H
ABC.cpp
#include "ABC.h"
class ABCExtended : public ABC<int, std::string> {
ABCExtended() :
ABC<int, std::string>()
{}
ABCExtended(int* pReturnValue) :
ABC<int, std::string>(pReturnValue)
{}
};
Thanks in advance.
xlC is not C++11 conformant. Shared_ptr is not available there in std:: namespace. It does have special namespace for 'experimental' features, and shared_ptr might be there. Those expereimentals are in std::tr1, and you need to compile with __ IBMCPP_TR1__.
shared_ptr is from the TR1 so it should be used from that namespace
change
std::shared_ptr mpRV;
to
std::tr1::shared_ptr mpRV;
Compile with
-D__IBMCPP_TR1__
I'm creating an UI abstraction layer for desktops. Now I'm implementing the functionality of the .NET framework. The annoying thing is that if I let the users create a CLR Windows Forms Application in Visual studio they can't use all the standard libraries like std::thread and if I let them create another type of application, the console shows up.
Is there a way to use clr with std::thread or, even better, is there a way to prevent the console from starting (or hide it from both the screen and the taskbar)with a CLR Console or CLR Empty project.
Thanks
Might be an old question, but I looked into this same problem before. Since CLR does not allow you to include std::thead at compile time, you could try to use it only at linking time. Normally you could resolve this be forward declaring the class in your header and including them only in your cpp files. However you can forward declare your own classes in header files, but you can't for classes in namespace std. According to the C++11 standard, 17.6.4.2.1:
The behavior of a C++ program is undefined if it adds declarations or
definitions to namespace std or to a namespace within namespace std
unless otherwise specified.
A workaround for this problem is to create a threading class that inherits from std::thread that you can forward declare. The header file for this class would look like:
#pragma once
#include <thread>
namespace Threading
{
class Thread : std::thread
{
public:
template<class _Fn, class... _Args> Thread(_Fn fn, _Args... args) : std::thread(fn, std::forward<_Args>(args)...)
{
}
private:
};
}
In the header file that you would like to use the thread you can do forward declare it like:
#pragma once
// Forward declare the thread class
namespace Threading { class Thread; }
class ExampleClass
{
public:
ExampleClass();
void ThreadMethod();
private:
Threading::Thread * _thread;
};
In your source file you can then use the theading class like:
#include "ExampleClass.h"
#include "Thread.h"
ExampleClass::ExampleClass() :
{
_thread = new Threading::Thread(&ExampleClass::ThreadMethod, this);
}
void ExampleClass::ThreadMethod()
{
}
Hope it might help anyone.
This is an old question, but in case someone hits the same problem: boost::thread is an "affordable" and practical replacement (provided you can use boost in your project). Strangely, it bypasses the incompatibility.
I'm working on a project in c++ and I stuck with no idea what is wrong. I've writen 4 classes and everything looked fine during work (under visual studio 2010). VS 'saw' all the definition, i could use auto-fill and sudgestions, but when I tried to compile the project it sudennly went blind. It's like I didnt include headers or something (which I did). The strange thing is there is no problem with working with those classes on VS (i can ctrl+space for hint, list of attributes and methods and all that stuff) but when i try to compile it says "ClassName" is not a type.
Quick sample of problem below:
ProButton.cpp:
#include "ProButton.h"
using namespace pGUI;
ProButton::ProButton( ... )
: ProControl( ... )
{
...
}
ProButton.h:
#ifndef __PRO_BUTTON__
#define __PRO_BUTTON__
#include <string>
#include "ProControl.h"
namespace pGUI
{
class ProButton :
public pGUI::ProControl
{
public:
//attributes
...
public:
//methods
...
};
}
#endif
but compiler says:
Error 291 error C2653: 'ProButton' : is not a class or namespace name
for this line in ProButton.cpp: ProButton::ProButton( ... )
It also says:
Error 23 error C2039: 'ProControl' : is not a member of 'pGUI'
Error 24 error C2504: 'ProControl' : base class undefined
and all similar errors for whole project. I have no idea what is wrong. Looks like my VS broke :D
Of course those (...) means there is code there, just not that important for now. I can upload all solution somewhere fi it will help.
edit//
About namespaces, all header files (classes declaration) are defined in namespace with:
namespace pGUI{
class ProClass
{
};
}
all definitions for these classes (in ProClass.cpp) are using:
using namespace pGUI;
at the beginning.
I think the problem is with order of including files.
Im not sure how this is supposed to be done. So far i have 4 classes that:
class ProGUI:
has a pointer to ProContainer
includes: ProContainer and ProControl
class ProContainer:
has pointers to: ProGUI and ProControl
class ProControl:
has a pointer to ProContainer
includes ProButton
is a base class for ProButton
class ProButton:
is a sub-class of ProControl
Those classes also uses irrlicht library and I'm not sure where to include it.
I had it included in my main file just before #include "ProGUI.h". This is also the only include in main. ProGUI.h .
//EDIT 2 -> solved
It was a problem with includes. I needed to rethink my inclusion order and add some forward declarations. Anyway that all seemed strange and took me a lot of time to figure i out. Thx for help. :)
It seems that you are using following statement:
using namespace pGUI;
Just before the class declaration:
class ProControl
{
};
Instead of using following approach:
namespace pGUI
{
class ProControl
{
};
}
The using namespace, as it says uses a namespace. You need to explicitly put something a namespace using namespace keyword followed by braces!
using namespace pGUI informs the compiler that it should look in the pGUI namespace to resolve existing names.
To declare or implement something in a namespace you need to be more specific. with either:
namespace pGUI
{
ProButton::ProButton( ... ) : ProControl( ... )
{
...
}
}
or:
pGUI::ProButton::ProButton( ... ) : ProControl( ... )
{
....
}
Personally, I consider any use of using namespace to be a lazy programmer hack that completely defeats the point of namespaces. But I digress. :)