Circular reference issue with struct and enum class - visual-c++

I have a header file (A):
namespace CChristianLifeMinistryDefines
{
using S_DISCUSSION_HIST_ITEM = struct tagDiscussionHistItem
{
CString strName;
Schools eSchool;
COleDateTime datMeeting;
};
using DiscussionItemHistList = list<S_DISCUSSION_HIST_ITEM>;
}
The above header file is included in another header file (B):
#include "ChristianLifeMinistryDefines.h"
using namespace CChristianLifeMinistryDefines;
enum class Schools
{
kMain,
kClass1,
kClass2,
kCount
};
The problem I have (and I understand why) is that Schools is referred to in the S_DISCUSSION_HIST_ITEM structure which is defined before the Schools enum.
Error C3646: 'eSchool': unknown override specifier
The enum was already defined in my project and can't be moved else things might break down when compiling.
What I have done is move the class definition from file B to file A. But was there another solution to this? I couldn't simply include header B in header A because I get a circular reference and I can't get my head around what I found on the internet.

Related

How to programmatically update .rgs files to reflect changes made in IDL files?

Is there any tool to update .rgs files to reflect change made in the IDL ?
rgs files are created by the ATL control wizzard but I can't find a way to refresh thoses files.
When we change the uuid of an interface (within the .IDL file), we are forced to changed by hand the "hard copy" values in those .rgs files. This is quiet prone to error.
I found this interesting project that intend to fill this gap but, accordingly the last comments, it didn't works any more since VC2005.
ATL CAtlModule implementation offers virtual CAtlModule::AddCommonRGSReplacements which you can override and add substitutions to remove hardcoded RGS values.
For example, my typical ATL code looks like this:
class CFooModule :
public CAtlDllModuleT<CFooModule>
{
[...]
// CAtlModule
HRESULT AddCommonRGSReplacements(IRegistrarBase* pRegistrar)
{
// Error handling omitted for code brevity
__super::AddCommonRGSReplacements(pRegistrar);
ATLASSERT(m_libid != GUID_NULL);
pRegistrar->AddReplacement(L"LIBID", _PersistHelper::StringFromIdentifier(m_libid));
pRegistrar->AddReplacement(L"FILENAME", CStringW(PathFindFileName(GetModulePath())));
pRegistrar->AddReplacement(L"DESCRIPTION", CStringW(AtlLoadString(IDS_PROJNAME)));
return S_OK;
}
In COM classes I override UpdateRegistry method to add tokens with third parameter of standard call _pAtlModule->UpdateRegistryFromResource.
As a result, many .RGS are shared between COM classes because hardcoded values are replaced with tokens. Specifically, there are no GUIDs in RGS files, e.g.:
HKCR
{
NoRemove CLSID
{
ForceRemove %CLSID% = s '%DESCRIPTION%'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
val AppID = s '%APPID%'
TypeLib = s '%LIBID%'
}
}
}
I'm not able to understand how %CLSID% is replaced with the COM class CLSID in roman-r's answer. There seem to be something missing in the answer.
Alternative solution from CodeProject: Registry Map for RGS files.
This solution introduces a custom registrymap.hpp header with a DECLARE_REGISTRY_RESOURCEID_EX extension that allows you to add RGS substitution macros to your COM classes. Example:
BEGIN_REGISTRY_MAP(CClassName)
REGMAP_ENTRY("PROGID", "MyLibrary.ClassName")
REGMAP_ENTRY("VERSION", "1")
REGMAP_ENTRY("DESCRIPTION", "ClassName Class")
REGMAP_UUID ("CLSID", CLSID_ClassName)
REGMAP_UUID ("LIBID", LIBID_MyLibraryLib)
REGMAP_ENTRY("THREADING", "Apartment")
END_REGISTRY_MAP()

Structure in two header files but with same name

I have these two header files in the following path:
...\xfs\XFS_WINCOR_03\INCLUDE_03_00\xfsbcr.hpp
...\xfs\XFS_WINCOR_03\INCLUDE_03_10\xfsbcr.hpp
Both of them have structures called wfs_bcr_status.
This structure is different in each header file but have the same name.
INCLUDE_03_00\xfsbcr.hpp
typedef struct wfs_bcr_status
{
WORD fwDevice;
WORD fwBCRScanner;
DWORD dwGuidLights[WFS_BCR_GUIDLIGHTS_SIZE];
LPSTR lpszExtra;
} WFSBCRSTATUS, * LPWFSBCRSTATUS;
/////////////////////////////////////////////////////////////////////////
INCLUDE_03_10\xfsbcr.hpp
typedef struct wfs_bcr_status
{
WORD fwDevice;
WORD fwBCRScanner;
DWORD dwGuidLights[WFS_BCR_GUIDLIGHTS_SIZE];
LPSTR lpszExtra;
WORD wDevicePosition;
USHORT usPowerSaveRecoveryTime;
} WFSBCRSTATUS, * LPWFSBCRSTATUS;
In my code I have a cdm_device class that is derived from the device class.
In device I include the first header and I use the structure in my methods.
#include "INCLUDE_03_00/xfsbcr.h"
In cdm_device i include the second header.
#include "INCLUDE_03_00/xfsbcr.h"
In my methods, when I want to get wDevicePosition and usPowerSaveRecoveryTime, I get an error because it's not recognizing the second header file (03_10) and look into the first header file (03_00) and they are not define there.
How can I fix this?

F# attributes, typeof, and "This is not a constant expression"

EDIT: Added a more complete example, which clarified the problem.
Some .NET attributes require a parameter of type Type. How does one declare these parameters in F#?
For example, in C# we can do this:
[XmlInclude(typeof(Car))]
[XmlInclude(typeof(Truck))]
class Vehicle { }
class Car : Vehicle { }
class Truck : Vehicle { }
But, in F# the following...
[<XmlInclude(typeof<Car>)>]
[<XmlInclude(typeof<Truck>)>]
type Vehicle() = class end
type Car() = inherit Vehicle()
type Truck() = inherit Car()
...results in a compiler error: This is not a constant expression or valid custom attribute value.
You should address a circular type dependency introduced by forward usage of types in attributes. The snippet below shows how this can be done in F#:
// Compiles OK
[<AttributeUsage(AttributeTargets.All, AllowMultiple=true)>]
type XmlInclude(t:System.Type) =
inherit System.Attribute()
[<XmlInclude(typeof<Car>)>]
[<XmlInclude(typeof<Truck>)>]
type Vehicle() = class end
and Car() = inherit Vehicle()
and Truck() = inherit Car()
Can you try putting together a more complete example that gives the error? I just quickly tried something similar and it works fine (in F# 3.0 in Visual Studio 2012):
type Car = C
type XmlInclude(typ:System.Type) =
inherit System.Attribute()
[<XmlInclude(typeof<Car>)>]
let foo = 0
I guess there is some tiny detail somewhere that confuses the F# compiler for some reason - but it should understand typeof (which is, in reality, a function) and allow its use in attributes.

c# cast a value obtained from FieldInfo

Grade in an Enum Structure.
var y=1;
var x= (Grade)y;
I'm trying to do the same thing as the above line but with a dynamic CLASSNAME.
FieldInfo field = typeof(Person).GetField("Grade");
var x= Convert.ChangeType(y ,field.FieldType);
I tried that. this works fine but not for enums.
I think the problem is with the way you are accessing the field on the enum. Enum fields are static. By default, the Type.GetField method uses binding flags equivalent to BindingFlags.Public|BindingFlags.Instance. This won't match an enum member.
If this is the problem you are having, then you can use typeof(Person).GetField("Grade",BindingFlags.Public|BindingFlags.Static) to get the FieldInfo for the field named "Grade" on the enum type named "Person". This assumes that your model looks like:
enum Person
{
Grade
}
There's another problem with your code that is compatible with enums as well. It's not totally obvious because your example seems to treat "Grade" as both a field and an type. If my previous suggestion doesn't describe your model, and the following does, then the problem is that you are using Convert.ChangeType which in this case should give you an InvalidCastException.
You need to find a different way to cast the value to your enum. If the class name is not known at compile-time, then I would suggest using linq expressions, e.g.
Type targetEnumType = typeof(Person).GetField("Grade");
ConstantExpression runtimeValue = Expression.Constant(y);
UnaryExpression cast = Expression.Convert(runtimeValue,targetEnumType);
LambdaExpression lambda = Expression.Lambda(cast);
Delegate getTheCastValue = lambda.Compile();
object value = getTheCastValue.DynamicInvoke();
This code assumes that your model looks something like
class Person
{
public Grade Grade;
}
enum Grade
{
First = 1,
Second = 2
}
However, looking at this, it becomes obvious that if Person is a non-generic class, then you would have to know the type of the Grade field at runtime, so you are better off just doing a (Grade)y cast, like in your example.

VC++ 2010 C2061 error

I am getting VC++ 2010 C2061 error on line:
#include "queryevaluator_p.h"
class QueryEvaluator {
public:
vector<AttrValue>* getCandidateList(QueryClause cl, int pos, ResultSet *computedRes);
...
Error 41 error C2061: syntax error : identifier 'ResultSet' h:\dropbox\sch\cs3202\code\source\includes\queryevaluator.h 40
ResultSet is a struct defined in "queryevaluator_p.h"
struct ResultSet{ //a set of result
bool valid;
vector<ResultRow> rows;
};
Whats wrong here? ResultSet can be used elsewhere
Maybe you have circular includes (queryevaluator_p.h includes the main header again) causing confusion. Depending on the exact setup this can lead to such an effect, because one of the files will have to be compiled first.
The solution would be to resolve the circular dependency by using a forward declaration instead of an include in one place. For example you could forward declare struct ResultSet instead of including the queryevaluator_p.h header.

Resources