I was trying to use the OMPTL in Visual Studio. As far as I understand it, I only need to set the /openmp option, in order for the OMPTL to use the multi-threaded implementation of some stl functions.
When I don't use /openmp everything is fine and OMPTL maps the functions to their normal stl counter parts, without multi-threading. With /openmp however, I get a compiler error:
Error 1 error C2572: 'omptl::transform_accumulate' : redefinition of default parameter : parameter 6 ..\include\omptl\omptl_numeric_extentions_par.h 132
The line in question says
template <class Iterator, class T, class UnaryFunction, class BinaryFunction>
T transform_accumulate(Iterator first, Iterator last, const T init,
UnaryFunction unary_op, BinaryFunction binary_op,
const unsigned P = omp_get_max_threads())
{
return ::omptl::_TransformAccumulate
<typename ::std::iterator_traits<Iterator>::iterator_category>
::transform_accumulate(first, last, init,
unary_op, binary_op, P);
}
Is there a way to fix this or is the OMPTL simply not usable with Microsoft's compiler?
The compiler does not seem to accept default parameters in this template declaration. Removing = omp_get_max_threads() from both declarations solved the problem for me.
Related
I'm trying to write a DLL to access the C++-only method Windows.Devices.Bluetooth.BluetoothLEDevice.Close() from a C# app. I seem to be able to access the class, but Visual Studio will not build if I try to use that one method. It is shown in the member list that comes up as you type, and there is no Intellisense error, just the build error.
using namespace Windows::Devices::Bluetooth;
__declspec(dllexport) void CloseBleDeviceUnmanaged(BluetoothLEDevice^device)
{
if (device->ConnectionStatus == BluetoothConnectionStatus::Connected) //no complaints for a property
{
device->GetDeviceSelector(); //no complaints for a method either
device->Close(); //Error C2039 | 'Close': is not a member of 'Windows::Devices::Bluetooth::BluetoothLEDevice'
}
return;
}
How do I get this to at least build?
(edit: removed extraneous syntax problem as per Nico Zhu - MSFT's answer)
You don't need to do any of this to call Close from C# -- just put it in a using(...) block and it will dispose (close) the object for you automatically. If the lifetime of the objection doesn't lend itself well to a using block, you can simply call IDisposabe.Dispose() on it directly.
For the compiler error, this is documented in MSDN since you should never call Close from C++/CX:
Close methods aren't callable through Visual C++ component extensions (C++/CX) on Windows Runtime class instances where the class implemented IClosable. Instead, Visual C++ component extensions (C++/CX) code for runtime classes should call the destructor or set the last reference to null.
The parameter of CloseBleDeviceUnmanaged method is Value Type in your case. When you pass a parameter to the method. The parameter will generate a copy. And the original parameter has not been changed. Please pass the
reference type parameter like the follow.
void DevicesTool::CloseBleDeviceUnmanaged(Windows::Devices::Bluetooth::BluetoothLEDevice^device)
{
if (device->ConnectionStatus == BluetoothConnectionStatus::Connected)
{
device->GetDeviceSelector();
device->Close();
}
}
As for the Close method, I have reproduced the issue in my side(target platform version 16299), and I have report this to related team. Please pay attention to the thread update.
As the support of C++/CLI was really bad in 2010 (no wizard for c++/cli!), one of my project is still VS2005 C++/CLI. Now is the time to migrate this last project. Unfortunately it comes with errors during compile time. Two of them I do not understand, because they worked perfectly before, try to compile this small snippet on VS2012:
enum class EMyEnum
{
Unknown,
NotBetter,
};
Array ^lEnums=Enum::GetValues(EMyEnum::typeid);
Object ^test=lEnums->GetValue(0);
EMyEnum t=(EMyEnum)test; // VS2012 ERROR -> Cannot cast
String ^thetext=t.ToString(); // VS2012 ERROR -> Left of ToString() needs object
Needless to say that in VS2005 it not only compile without error or warning, it also works as expected.
Yes, this is a problem in VS2012 and up. This is caused by the C++11 language standard adopting the enum class syntax. The C++/CLI compiler can now no longer distinguish a managed enum type from an unmanaged one. The cast from Object^ is only valid for a managed enum.
The workaround is silly but effective, you should explicitly specify the accessibility of the enum class. Something that's not legal in C++11 but valid in C++/CLI. Fix:
private enum class EMyEnum // Note: added private
{
Unknown,
NotBetter,
};
Or use public.
I just filed this bug on Microsoft Connect regarding the inability to compile the following toy snippet of code:
template <typename... P> struct S {
template <void(*F)(P...)> static void T() { }
};
void A(int, float) { }
int main() { S<int, float>::T<&A>(); }
The error is:
test.cpp(2): error C3520: 'P' : parameter pack must be expanded in this context
Essentially, I cannot unpack a variadic type inside of a function signature when used as a template parameter. This code is (I think) legal; at least, GCC 4.7, Clang 3.0, and ICC 13 all support it.
I've seen this SO question but no workarounds are requested or given, which is what I'm looking for.
While not super critical (obviously I've been getting by without variadic templates for many years now) this pattern is of particular importance to some of the work I'd like to do and some articles I'd like to do on C++11 reflection techniques for serialization, script binding, etc. which is something I'd like to be useful to Visual Studio users (as it is by far the dominant compiler toolset in my industry). I'd like to hope that Microsoft's engineers will be able to fix this by 2013 RTM, but I'm not holding my breath.
A toy (from memory this time) sample of how this is being used is something like (minus the macros that make it slightly easier to use):
Reflect<MyType>("MyType")
.bind("GetMatrix", mat44, &MyType::GetMatrix>()
.bind("Display", void, &MyType::Display>();
Of course this can all be done without variadic templates. It just takes large masses of code and accepting limitations to the maximum arity of bound member functions, of course. And yes, passing the functions as a template parameter is of import, due to the nature of how member function pointers work in Visual Studio (variable size) and a desire to achieve efficiency on par with Impossibly Fast C++ Delegates (in my niche of the C++ community, this level of optimization can sometimes actually matter) which negates the option of using std::function or similar designs.
Is there a work-around for this VS bug? Or any other way to use variadic templates to use a (compile-time) function pointer parameter in VC++12?
Not sure why but simplifying with a typedef seems to work:
template <typename... P>
struct S
{
typedef void (*MyFunc)(P...);
template <MyFunc myFunc>
static void foo() {}
};
void foo2(int, float) {}
int main()
{
S<int, float>::foo<&foo2>();
}
At least on the Visual Studio 2013 Ultimate Preview.
I'm working with a third party COM server with its own custom interface that sets and gets structs as some of its properties. As it happens I'm using C++ for the client. I've posted some representative code from the IDL file below with names changed and GUIDs removed.
Is the packing of the structure defined or is it just good fortune that my client code happens to use the same packing settings that the COM server was built with? Would it be likely to go wrong in projects where the default C++ compiler packing settings had been changed? Is there a pragma pack setting that I could use to make sure the client compiler packing settings are correct?
I can't see any packing pragmas or statements in either the IDL or the header file generated from MIDL. What would happen if the client was in C# or VB instead? Is the packing behaviour more clearly specified if called via the IDispatch mechanism?
struct MyStruct
{
int a, b;
};
[
object,
uuid( /* removed */ ),
dual,
nonextensible,
pointer_default(unique)
]
interface IVideoOutputSettings : IDispatch{
[propget, id(1), HRESULT MyProperty([out, retval] struct MyStruct* pVal);
[propput, id(1), HRESULT MyProperty([in] struct MyStruct newVal);
/* other methods */
};
The default packing is along 8-byte boundaries, according to the MIDL command line switch reference here:
/Zp switch # MSDN (MIDL Language Reference)
Other parts of your code are more likely to break first if the pack value is changed, as the IDL file is usually pre-compiled ahead of time, and it is rare that someone will deliberately alter the command line switches given to MIDL (but not so rare that someone could fiddle with the C-scope #pragma pack and forget to restore the default state).
If you have a good reason to alter the setting, you can explicitly set the packing with a pragma pack statement.
pragma Attribute # MSDN (MIDL Language Reference)
It is pretty good fortune that no party has changed any setting that would interfere with the default packing. Can it go wrong? Yes, if someone goes out of their way to change the defaults.
When using an IDL file, the details are typically compiled into a typelib (.tlb), and it is assumed that the platform are the same for both servers and clients when using the same typelib. This is suggested in the footnotes for the /Zp switch, as certain values will fail against certain non-x86 or 16-bit targets. There can also be 32bit <-> 64bit conversion cases that could cause expectations to break. Unfortunately I don't know if there are even more cases out there, but the defaults do work with minimal fuss.
C# and VB do not have any intrinsic behavior to handle information in a .tlb; instead, a tool like tlbimp is typically used to convert COM definitions into definitions usable from .NET. I can't verify whether all expectations succeed between C#/VB.NET and COM clients and servers; However, I can verify that using a specific pragma setting other than 8 will work if you reference a .tlb that was created from an IDL compiled under that setting. While I wouldn't recommend going against the default pragma pack, here are the steps to perform if you'd like a working example to use as a reference. I created a C++ ATL project and a C# project to check.
Here are the C++ side instructions.
I created an ATL project called SampleATLProject with the default settings in Visual Studio 2010, no fields changed. This should create a dll project for you.
Compiled the project to assure that the proper C-side interface files are being created (SampleATLProject_i.c and SampleATLProject_i.h).
I added an ATL Simple Object called SomeFoo to the project. Again, no defaults were altered. This creates a class called CSomeFoo that is added to your project.
Compile SampleATLProject.
I right-clicked the SampleATLProject.idl file, then under the MIDL settings, set the Struct Member Alignment to 4 bytes (/Zp4).
Compile SampleATLProject.
I altered the IDL to add a struct definition called 'BarStruct'. This entailed adding a C-style struct definition with the MIDL uuid attribute, and an entry in library section referencing the struct definition. See snippet below.
Compile SampleATLProject.
From the Class View, I right-clicked on ISomeFoo and added a method called FooIt, that takes a struct BarStruct as an [in] parameter called theBar.
Compile SampleATLProject.
In SomeFoo.cpp, I added some code to print out the size of the struct and throw up a Message Box containing the details.
Here is my IDL for the ATL project.
import "oaidl.idl";
import "ocidl.idl";
[uuid(D2240D8B-EB97-4ACD-AC96-21F2EAFFE100)]
struct BarStruct
{
byte a;
int b;
byte c;
byte d;
};
[
object,
uuid(E6C3E82D-4376-41CD-A0DF-CB9371C0C467),
dual,
nonextensible,
pointer_default(unique)
]
interface ISomeFoo : IDispatch{
[id(1)] HRESULT FooIt([in] struct BarStruct theBar);
};
[
uuid(F15B6312-7C46-4DDC-8D04-9DEA358BD94B),
version(1.0),
]
library SampleATLProjectLib
{
struct BarStruct;
importlib("stdole2.tlb");
[
uuid(930BC9D6-28DF-4851-9703-AFCD1F23CCEF)
]
coclass SomeFoo
{
[default] interface ISomeFoo;
};
};
Inside the CSomeFoo class, here is the implementation for FooIt().
STDMETHODIMP CSomeFoo::FooIt(struct BarStruct theBar)
{
WCHAR buf[1024];
swprintf(buf, L"Size: %d, Values: %d %d %d %d", sizeof(struct BarStruct),
theBar.a, theBar.b, theBar.c, theBar.d);
::MessageBoxW(0, buf, L"FooIt", MB_OK);
return S_OK;
}
Next, on the C# side:
Go to the debug or desired output directory for SampleATLProject and run tlbimp.exe on the .tlb file generated as part of the C++ project output. The following worked for me:
tlbimp SampleATLProject.tlb /out:Foo.dll /namespace:SampleATL.FooStuff
Next, I created a C# console application, and added a reference to Foo.dll to the project.
In the References folder, go to the Properties for Foo and turn off Embed Interop Types by setting it to false.
I added a using statement to reference the namespace SampleATL.FooStuff as given to tlbimp, added the [STAThread] attribute to Main() (the COM apartment models have to match for in-proc consumption), and added some code to call the COM component.
Tlbimp.exe (Type Library Importer) # MSDN
Here is the source code for that console app.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SampleATL.FooStuff;
namespace SampleATLProjectConsumer
{
class Program
{
[STAThread]
static void Main(string[] args)
{
BarStruct s;
s.a = 1;
s.b = 127;
s.c = 255;
s.d = 128;
ISomeFoo handler = new SomeFooClass();
handler.FooIt(s);
}
}
}
Finally, it runs and I get a modal popup with the following string displayed:
Size: 12, Values: 1 127 255 128
To be sure that a pragma pack change can be made (as 4/8 byte packing are the most common alignments used), I followed these steps to change it to 1:
I returned to the C++ project, went to the properties for SampleATLProject.idl and changed the Struct Member Alignment to 1 (/Zp1).
Recompile SampleATLProject
Run tlbimp again with the updated .tlb file.
A warning icon will appear on the .NET File Reference to Foo, but may disappear if you click on the reference. If it doesn't, you can remove and re-add the reference to the C# console project to be sure it is using the new updated version.
I ran it from here and got this output:
Size: 12, Values: 1 1551957760 129 3
That's weird. But, if we forcefully edit the C-level pragma in SampleATLProject_i.h, we get the correct output.
#pragma pack(push, 1)
/* [uuid] */ struct DECLSPEC_UUID("D2240D8B-EB97-4ACD-AC96-21F2EAFFE100") BarStruct
{
byte a;
int b;
byte c;
byte d;
} ;
#pragma pack(pop)
SampleATLProject is recompiled here, no changes to the .tlb or .NET project, and we get the following:
Size: 7, Values: 1 127 255 128
Regarding IDispatch, it depends on whether your client is late-bound. Late-bound clients have to parse the type information side of IDispatch and discern the proper definitions for non-trivial types. The documentation for ITypeInfo and TYPEATTR suggests that it is possible, given that the cbAlignment field provides the information necessary. I suspect most will never alter or go against the defaults, as this would be tedious to debug if things went wrong or if the pack expectations had to change between versions. Also, structures are not typically supported by many scripting clients that can consume IDispatch. One can frequently expect that only the types governed by the IDL oleautomation keyword are supported.
IDispatch interface # MSDN
IDispatch::GetTypeInfo # MSDN
ITypeInfo interface # MSDN
TYPEATTR structure # MSDN
oleautomation keyword # MSDN
Yes, structs are a problem in COM. If you use IUnknown based interfaces then you'll have to roll the dice with proper compiler settings. Few reasons to change the default.
If you use COM Automation then you have to declare the struct with a typedef in the .IDL. So that the client code can use IRecordInfo to access the structure properly, guided by the type library info. All you have to do is ensure that your compiler's /Zp setting matches midl.exe's /Zp setting. Not hard to do.
You sail around the problem entirely by realizing that any structure can be described by an interface with properties. Now it doesn't matter.
I have a vector class that I want to be able to input/output from a QTextStream object. The forward declaration of my vector class is:
namespace util {
template <size_t dim, typename T>
class Vector;
}
I define the operator<< as:
namespace util {
template <size_t dim, typename T>
QTextStream& operator<<(QTextStream& out, const util::Vector<dim,T>& vec)
{
...
}
template <size_t dim, typename T>
QTextStream& operator>>(QTextStream& in,util::Vector<dim,T>& vec)
{
..
}
}
However, if I ty to use these operators, Visual C++ returns this error:
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QTextStream' (or there is no acceptable conversion)
A few things I tried:
Originaly, the methods were defined as friends of the template, and it is working fine this way with g++.
The methods have been moved outside the namespace util
I changed the definition of the templates to fit what I found on various Visual C++ websites.
The original friend declaration is:
friend QTextStream& operator>>(QTextStream& ss, Vector& in) { ... }
The "Visual C++ adapted" version is:
friend QTextStream& operator>> <dim,T>(QTextStream& ss, Vector<dim,T>& in);
with the function pre-declared before the class and implemented after. I checked the file is correctly included using:
#pragma message ("Including vector header")
And everything seems fine. Doesn anyone has any idea what might be wrong?
Note: the definition of the operator doesn't even appears in the list of operator<< found.
I encountered the same problem and I think I figured out what was going on. For some reason, MSVC sometimes mistakes std::endl, for the endl defined in QTextStream (of course if you are "using namespace std" anywhere, this behavior is appropriate).
Also, I think MSVC sometimes gets confused with std::strings (maybe if they are const or addresses or something like that) with QTextStream.
MSVC tends to be very particular about the const/& variants of overloads, especially in cases where there may be some ambiguity. I have seen this before with non-QT code with some overloaded functions.
Of course, the error messages are just confusing so, it might be that my analysis is wrong here.
It is hard to say without seeing the actual instantiation site, but so far what I noticed is that the error says that there is no suitable operator for QTextStream, and your implementations use QTextStream&. This might be because you are trying to use the operator on an R-Value, these can be converted to const &, but not only &.
You forgot to make the overload that took a const Vector actually const.