I have a C++/CLI class library project in VS2005 that i am having some problems with. I have defined a class called Languages which is a an enum class. which looks like this:
"Language.cpp"
namespace Company
{
namespace product
{
public eunm class Languages : int
{
English = 1,
German = 2,
//etc for other languages
};
}
};
I then have another class that tries to references this which lives in the same namespace:
"Language.cpp"
namespace Company
{
namespace product
{
public class LanguageConsumer
{
public:
LanguageConsumer()
{
}
public:
Languages DoSomething(Languages input)
{
if (input == Languages::English)
{
//Do something and return
}
};
}
};
However my project doensn't compile. From what i can figure out the different classes can't see each other even thought they are in the same namespace. I assume that i might need to have header files and #includes for the header files but i just don't know enough about C++/CLI to be sure (i come from C# background with hardly any C experience) and i have tried as many different combinations as i can think of. I'm sure i'm missing something very obvious to anybody who knows what they are doing, but alas i do not.
Thanks in advance.
C++/CLI still compiles like C++, file files are compiled separately and then linked together. This is different from C# which compiles all the files together. At compile time the files don't know about each other so the code doesn't compile (what is this enum?!). You need to have the enum definition in the same file (compilation unit) as the class.
The simple way to do this is to move the code into the same file. The header file solution is to move the enum definition into a header file and then include it (#include) in the other file. #include inserts the text of another file, giving the same effect.
Related
I'm attempting to convert my existing C++/CX code to C++/WinRT in order to figure out whether that would enable me to compile that code using Clang. However, I'm stuck early on.
The C++/CX code that I need to convert is used to build a Direct3D component (based on SwapChainPanel) that is eventually utilized in a Windows UWP app that is written in C#. The problem I'm facing is that I just don't manage to convert my customized SwapChainPanel to C++/WinRT.
The code looks as follows:
namespace Why::Does::This::Not::Work
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class BaseView : public Windows::UI::Xaml::Controls::SwapChainPanel
{
protected private:
BaseView();
// Lots of other stuff
};
}
namespace Why::Does::This::Not::Work
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CustomView sealed : public BaseView
{
public:
CustomView();
// ...
event AnimationEventHandler^ AnimationStarted;
private protected:
// Lots of private protected stuff
};
}
namespace Why::Does::This::Not::Work
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class AnimationEventArgs sealed
{
public:
AnimationEventArgs() {}
AnimationEventArgs(int start, int end)
{
Start = start;
End = end;
}
property int Start;
property int End;
};
[Windows::Foundation::Metadata::WebHostHidden]
public delegate void AnimationEventHandler(Platform::Object^ sender, AnimationEventArgs^ e);
}
As far as I'm able to interpret the documentation I need to do what is described under If you're authoring a runtime class to be referenced in your XAML UI in the documentation.
So, it seems to me that I'd need to author an IDL file in order to generate the COM stuff that is required. However, I cannot even make the skeleton IDL compile:
namespace Why
{
namespace Does
{
namespace This
{
namespace Not
{
namespace Work
{
runtimeclass CustomView : Windows::UI::Xaml::Controls::SwapChainPanel
{
CustomView();
}
}
}
}
}
}
When attempting to compile the above code all I'm getting is
error MIDL2025: [msg]syntax error [context]: expecting { near ":"
error MIDL2026: [msg]cannot recover from earlier syntax errors; aborting compilation
I apologize if you view this as a stupid question. I have read the corresponding documentation but I just fail to comprehend what is really going on when utilizing C++/WinRT. I have plenty of experience with C++ but zero with COM which means it is everything else than straight forward to understand C++/WinRT.
If someone can lend me a hand translating the above C++/CX code to C++/WinRT that would be highly appreciated. Please don't just point me to the documentation, that just doesn't help.
EDIT:
Modifying the sample IDL code as follows successfully compiled it:
namespace Why
{
namespace Does
{
namespace This
{
namespace Not
{
namespace Work
{
[default_interface]
runtimeclass CustomView : Windows.UI.Xaml.Controls.SwapChainPanel
{
CustomView();
}
}
}
}
}
}
However, exposing a user control to another language, in my case C#, such as the one inheriting from SwapChainPanel is dramatically more complex than doing the same thing in C++/CX. There's an IDL to deal with that is not easy to handle because there don't seem to be any complex samples around. That IDL generates several header files that I'm not really sure about what to do with because the documentation is lacking and samples are sparse. C++/WinRT is not for the faint-hearted and its complexity compared to C++/CX is simpy much higher.
It seems to me that to really understand C++/WinRT it is a necessity to have a good grasp of COM because compared to C++/CX, C++/WinRT does a poor job of hiding those COM related internals. This is especially the case when dealing with DirectX. Add to this an IDL that in itself is hard to deal with and a documentation of it that might suffice to get simple samples up and running but does not help much when porting a full fledged C++/CX app.
Doing what we do with C++/CX in C++/WinRT is just not economical for and we will stay on C++/CX until C++/WinRT becomes much more user friendly. Eliminating the need for the IDL (see https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/36095386-get-rid-of-idl-for-c-winrt-components) would help too.
Without the prospect of being able to compile our code using Clang I would not even think about moving away from C++/CX. Microsoft shouldn't wonder that the adoption of C++/WinRT is slow. If they seriously want to change that they have to lower the entry barrier considerably.
Fully qualified type names in IDL use the period (.) as the namespace separator. A working IDL file would look like this:
namespace Why
{
namespace Does
{
namespace This
{
namespace Not
{
namespace Work
{
runtimeclass CustomView : Windows.UI.Xaml.Controls.SwapChainPanel
{
CustomView();
}
}
}
}
}
}
There's fairly complete documentation at Microsoft Interface Definition Language 3.0 reference. Even with that, it's often challenging to make any sense out of MIDL error messages.
I have a VC++ 2010 solution containing two projects: ProjectX and ProjectXTests. In the current configuration, ProjectX builds as a static library and ProjectXTests as a DLL intended to test various methods in ProjectX. Now, in ProjectX I have a class User with a method getUserName(), as follows:
// User.h
public ref class User
{
public:
User(String^ userName);
String^ getUserName();
private:
String^ userName;
};
The constructor and method are implemented in User.cpp. In ProjectXTests, I have a class UserTests, which tests, among other things, the getUserName() method, in a, say, getUserNameTest() method. It is declared in UserTests.h and implemented as follows in UserTests.cpp:
// UserTests.cpp
#include "UserTests.h"
#include "User.h"
void UserTests::getUserNameTest()
{
User^ testUser = gcnew User("name");
Assert::AreEqual("name", testUser->getUserName());
}
In the project properties (Common Properties -> Framework and References) of ProjectXTests, I have added a reference to ProjectX. In VC++ Directories, I have added the appropriate directories for header files and library files. When building the solution, the header file "User.h" is found. However, I get a link error
error LNK2020: unresolved token (06000005) User::getUserName
The same thing happens for all other methods being tested. I just can't figure out why this happens. So far, the only thing I've found to work, is to include the file "User.cpp" instead of "User.h" in "UserTests.cpp", but this seems like cheating. Does anybody know what I might be missing?
Somehow you have to include the code from ProjectX in ProjectXTests. This is not done by literally using the #include directive, instead the simplest is to add the source files from ProjectX to the ProjectXTests project workspace. If ProjectX is made as a static of dynamic library, then link with that instead.
Is it possible to extend or modify the code of a C# class at runtime?
My question specifically revolves around Monkey Patching / Duck Punching or Meta Object Programming (MOP), as it happens in scripting languages such as Groovy, Ruby etc.
For those still stumbling on this question in the present day, there is indeed a present-day library called Harmony that relatively-straightforwardly enables such monkey-patching at runtime. Its focus is on video game modding (particularly games built with Unity), but there ain't much stopping folks from using it outside of that use case.
Copying the example from their introduction, if you have an existing class like so:
public class SomeGameClass
{
public bool isRunning;
public int counter;
private int DoSomething()
{
if (isRunning)
{
counter++;
}
return counter * 10;
}
}
Then Harmony can patch it like so:
using HarmonyLib;
using Intro_SomeGame;
public class MyPatcher
{
// make sure DoPatching() is called at start either by
// the mod loader or by your injector
public static void DoPatching()
{
var harmony = new Harmony("com.example.patch");
harmony.PatchAll();
}
}
[HarmonyPatch(typeof(SomeGameClass))]
[HarmonyPatch("DoSomething")]
class Patch01
{
static AccessTools.FieldRef<SomeGameClass, bool> isRunningRef =
AccessTools.FieldRefAccess<SomeGameClass, bool>("isRunning");
static bool Prefix(SomeGameClass __instance, ref int ___counter)
{
isRunningRef(__instance) = true;
if (___counter > 100)
return false;
___counter = 0;
return true;
}
static void Postfix(ref int __result)
{
__result *= 2;
}
}
Here, we have a "prefix" patch which gets inserted before the original method runs, allowing us to set variables within the method, set fields on the method's class, or even skip the original method entirely. We also have a "postfix" patch which gets inserted after the original method runs, and can manipulate things like the return value.
Obviously this ain't quite as nice as the sorts of monkey-patching you can do in e.g. Ruby, and there are a lot of caveats that might hinder its usefulness depending on your use case, but in those situations where you really do need to alter methods, Harmony's a pretty proven approach to doing so.
Is it possible to extend or modify the code of a C# class at run-time?
No it is not possible to do this in .NET. You could write derived classes and override methods (if they are virtual) but you cannot modify an existing class. Just imagine if what you were asking was possible: you could modify the behavior of some existing system classes like System.String.
You may also take a look at Extension methods to add functionality to an existing class.
You can add functionality, but you cannot change or remove functionality.
You can extend classes by adding extra methods, but you cannot override them because added methods have always lower priority than existing ones.
For more info, check Extension Methods in C# Programming Guide.
I'm porting a medium-sized CRUD application from .Net to Qt and I'm looking for a pattern for creating persistence classes. In .Net I usually created abstract persistence class with basic methods (insert, update, delete, select) for example:
public class DAOBase<T>
{
public T GetByPrimaryKey(object primaryKey) {...}
public void DeleteByPrimaryKey(object primaryKey) {...}
public List<T> GetByField(string fieldName, object value) {...}
public void Insert(T dto) {...}
public void Update(T dto) {...}
}
Then, I subclassed it for specific tables/DTOs and added attributes for DB table layout:
[DBTable("note", "note_id", NpgsqlTypes.NpgsqlDbType.Integer)]
[DbField("note_id", NpgsqlTypes.NpgsqlDbType.Integer, "NoteId")]
[DbField("client_id", NpgsqlTypes.NpgsqlDbType.Integer, "ClientId")]
[DbField("title", NpgsqlTypes.NpgsqlDbType.Text, "Title", "")]
[DbField("body", NpgsqlTypes.NpgsqlDbType.Text, "Body", "")]
[DbField("date_added", NpgsqlTypes.NpgsqlDbType.Date, "DateAdded")]
class NoteDAO : DAOBase<NoteDTO>
{
}
Thanks to .Net reflection system I was able to achieve heavy code reuse and easy creation of new ORMs.
The simplest way to do this kind of stuff in Qt seems to be using model classes from QtSql module. Unfortunately, in my case they provide too abstract an interface. I need at least transactions support and control over individual commits which QSqlTableModel doesn't provide.
Could you give me some hints about solving this problem using Qt or point me to some reference materials?
Update:
Based on Harald's clues I've implemented a solution that is quite similar to the .Net classes above. Now I have two classes.
UniversalDAO that inherits QObject and deals with QObject DTOs using metatype system:
class UniversalDAO : public QObject
{
Q_OBJECT
public:
UniversalDAO(QSqlDatabase dataBase, QObject *parent = 0);
virtual ~UniversalDAO();
void insert(const QObject &dto);
void update(const QObject &dto);
void remove(const QObject &dto);
void getByPrimaryKey(QObject &dto, const QVariant &key);
};
And a generic SpecializedDAO that casts data obtained from UniversalDAO to appropriate type:
template<class DTO>
class SpecializedDAO
{
public:
SpecializedDAO(UniversalDAO *universalDao)
virtual ~SpecializedDAO() {}
DTO defaultDto() const { return DTO; }
void insert(DTO dto) { dao->insert(dto); }
void update(DTO dto) { dao->update(dto); }
void remove(DTO dto) { dao->remove(dto); }
DTO getByPrimaryKey(const QVariant &key);
};
Using the above, I declare the concrete DAO class as following:
class ClientDAO : public QObject, public SpecializedDAO<ClientDTO>
{
Q_OBJECT
public:
ClientDAO(UniversalDAO *dao, QObject *parent = 0) :
QObject(parent), SpecializedDAO<ClientDTO>(dao)
{}
};
From within ClientDAO I have to set some database information for UniversalDAO. That's where my implementation gets ugly because I do it like this:
QMap<QString, QString> fieldMapper;
fieldMapper["client_id"] = "clientId";
fieldMapper["name"] = "firstName";
/* ...all column <-> field pairs in here... */
dao->setFieldMapper(fieldMapper);
dao->setTable("client");
dao->setPrimaryKey("client_id");
I do it in constructor so it's not visible at a first glance for someone browsing through the header. In .Net version it was easy to spot and understand.
Do you have some ideas how I could make it better?
As far as I know there is nothing ready made that gives to this facility directly in qt. There are some possible approaches.
Implement the fields as Q_PROPERTY, the are then reflected through the Metaclass system and can be used to implement generic DAO functionality
You could still use the QSqlTableModel but encapsulate writes with transactions, if a transaction fails, refresh the model from the DB. Feasibility depends on the size of the data that you hold in the the model.
We currently use a TableModel/QSqlRecord based approach for reading and writing, there is no ORM mapping done in our system. I have been trying to engineer a more generic approach but the refactoring work that we would have to do to get there is to costly at the moment.
This link http://giorgiosironi.blogspot.com/2009/08/10-orm-patterns-components-of-object.html is not Qt related but a good overview of implementation patterns
If you want an ORM which only depends on Qt and builds upon Qt's Meta-Object System to provide instrospection, you might consider trying QDjango. On top of the basic create/update/delete operations at the model level, it provides a queryset template class (modeled after django's querysets) which allows to build fairly complex lookups. QtScript integration is also underway.
Tegesoft has recently release a new version of its library named CAMP that provide C++ runtime reflexion as you are using in .Net. I think this will allow you to achieve your application like you have done in .Net.
There is also a new open source ORM C++ library : QxOrm. QxOrm is based on QtSql Qt module to communicate with database and boost::serialization to serialize your data with xml and binary format. The web site is in french but quick sample code and tutorial code is in english (a translation is in progress...).
...And one more new Qt ORM: QST: QsT SQL Tools (latest stable version - 0.4.2a release).
QST provides mechanism to generate simple SQL queries: SELECT, INSERT, DELETE, UNPDATE and EXECUTE. Version 0.4 uses T-SQL; new version - 0.5 - will use PostgreSQL by default. You will find, this ORM based on original, unusual conceptions. For example, it integrated with Qt Interview system, so you can setting up view representation (column widths, titles) much easy.
There are example projects for versions 0.3 and 0.4: TradeDB 0.3, TradeDB 0.4. TradeDB 0.4 should be useful to start learning QST.
This seems like an excellent technique. I am, however, having some problems getting my prototype to compile n link....
I've implemented the basics as you describe and call the DAO class to retrieve an instance of one of my DB-resident objects.
Here are the statements calling this these model classes:
_db = <create QSqlDatabase>;
dao = new UniversalDAO (_db);
AddressDAO * aDAO = new AddressDAO (dao);
Address addr = aDAO->getByPrimaryKey(QVariant(1));
In my AddressDAO.cpp, I have:
template<class Address>
Address SpecializedDAO<Address>::getByPrimaryKey(const QVariant &key)
{ }
At link time, I get the following:
undefined reference to
`SpecializedDAO<Address>::getByPrimaryKey(QVariant const&)'
How would I correctly implement the methods in the SpecializedDAO class?
Update:
Stupid me, stupid me, stupid me.... I mostly got this to work. The issues....
My model classes (DTOs) are wrapped in namespaces and I use macros to define and use these namespaces. Plus, I tried to use a good hierarchy for these classes and found that moc has a reeeeal problem with class hierarchies wrapped in namespaces....
I fergot that function definitions of template classes need to be in the header file - can't be in separate compilation units.
qmake doesn't deal with (header file) dependencies very well when crossing library boundaries. I have my model stuff in a shared lib and the 'main()' function (in a separate directory) was trying to read a record from the DB. The 'main()' C file wasn't getting re-compiled when I changed my model class header file...
Here are more details:
In SpecializedDAO.h:
template<class DTO>
DTO SpecializedDAO<DTO>::getByPrimaryKey(const QVariant &key)
throw (FlowException)
{
DTO obj;
dao->getByPrimaryKey(static_cast<QObject &> (obj), key);
return obj;
}
In UniversalDAO.cpp:
void
UniversalDAO::getByPrimaryKey (QObject & dto, const QVariant & key)
{
<retrieve properties from 'dto' n build up QSqlQuery>
<execute QSqlQuery 'SELECT...' to retrieve record>
<call dto.setProperty() on all fields>
}
A current outstanding issue is use of user-defined types for property types in my DTO classes. I'm trying to use std::string vs. QString, but no matter what I tried (Q_DECLARE_METATYPE(std::string), qRegisterMetaType<std::string>(), etc., nothing seemed to work.... had to revert to Qt-based types. bummer....
So, I have two classes...Very basic in structure. I try to import one into the other, and declare a new object of that class type...however, it seems to read the class name as the name of a variable?!
The header class provided below will not read the "ApplicationManager" class properly.
Code:
####ifndef _GAME_H_
####define _GAME_H_
####include "application.h"
####include "applicationmanager.h"
class Game : public Application
{
public:
Game();
~Game();
void LoadContent() override;
void UnloadContent() override;
void Draw() override;
private:
//int ApplicationManager; //WHY DOES THIS COMPILE??!
ApplicationManager management; //This DOES NOT WORK?
};
####endif
Here is the header for the "ApplicationManager" class.
Code:
####ifndef _APPMANAGER_H_
####define _APPMANAGER_H_
####include "game.h"
####include "application.h"
class ApplicationManager
{
public:
ApplicationManager(void);
~ApplicationManager(void);
private:
};
####endif
The error that occurs, tells me that I need a ";" before "management", and that "ApplicationManager" is missing a type specifier, so it is assumed to be default-type int.
...any ideas why it won't compile properly? Can someone else try this and report the results? I copied the code, and pasted it in a different solution, to see if something became corrupted....it still didn't work.
You have a cyclic reference. When game.h is included from applicationmanager.h, the ApplicationManager class has not yet been read by the compiler.
To fix, remove the line
#include "game.h"
from applicationmanager.h.
Why do you have circular dependency between Game.h and AppicationManager.h?
Aside from that, I'd say check your header guard (#ifdef _*_H) in Application.h. A fairly often occurence in C++, when copy/pasting code or copying files, is to forget to change the header guard define name for a new class, so you end up with two different headers guarded by the same define. In which case, if both are included into some other file, only the first will actually be expanded into anything useful.
THe error message is some what misleading. It basically says "For some reason (probably an error in the referenced type) I cannot recognize the type you're using (in you case ApplicationManager)".
If you need ApplicationManager to know about Game make a pure virtual base class (interface in other terms) and have Game inherit from that (with out extending the interface) and have ApplicationManager include the base class header file