COM Interop throwing EEMessageException when invoking managed DLL - com

What a nightmare COM interop is proving to me. I have a simple managed DLL containing a WPF window. I have a simple ViewController class that will eventually be launching this window but for now has an empty method that does nothing.
I have created a managed wrapper for this managed DLL, that exposes an interface registered for COM interop. I can call into my managed wrapper OK. I can display a MessageBox in the entry point of my managed wrapper DLL. However, if I attempt to call ANY method on this ViewController class in the DLL I am wrapping, I get this:
First-chance exception at 0x7c812aeb (kernel32.dll) in MfcVSApp1.exe: Microsoft C++ exception: EEMessageException at memory location 0x0012cb30..
It all worked yesterday apparently. Now some code:
My wrapper entities:
[Guid("83C799E0-9808-40c2-A1AB-80BCB77A3B18")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface IMaryln
{
void GetEphemeris(DateTime date, double latitude, double longitude);
/// <summary>
///
/// </summary>
/// <param name="date"></param>
/// <param name="latitude"></param>
/// <param name="longitude"></param>
void GetEphemeris1(Int64 millSecsSince1970, double latitude, double longitude);
}
[Guid("144DB386-D8EF-41a8-B9B1-57EE8A64600C")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ManagedProxy.Maryln")]
[ComVisible(true)]
public class Maryln : IMaryln
{
#region IMaryln Members
public Maryln()
{
System.Diagnostics.Debugger.Launch();
}
public void GetEphemeris(DateTime date, double latitude, double longitude)
{
//new EphemerisViewController().GetEphemeris(date, latitude, longitude);
}
public void GetEphemeris1(Int64 nanoSecsSince1970, double latitude, double longitude)
{
// This method does not throw. However, it will not be executed
// if any method in EphemerisViewController is called.
MessageBox.Show("Called from c++" + nanoSecsSince1970.ToString());
try
{
//new Maryln().Test(); // this will not throw
new EphemerisViewController().GetString(); // this will
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void Test()
{
MessageBox.Show("maryln test");
}
#endregion
}
The Managed DLL, referenced by the managed wrapper DLL, contains a UserControl and this ViewController:
public class EphemerisViewController
{
public EphemerisViewController()
{
}
public void GetString()
{
MessageBox.Show("me");
}
}
This DLL was also registered for COM interop but then I unchecked that option as it did not help matters. Gurus on board, I need help here. This has consumed two working days already and I have taken 3 steps back from where I started. It all worked yesterday.
Addition
The native client is consuming my wrapper as follows:
void CMfcVSApp1Doc::LaunchEphemrisDialog()
{
HRESULT hr;
CoInitialize(NULL);
try
{
ManagedProxy::IMarylnPtr maryln(__uuidof(ManagedProxy::Maryln));
LONG64 time = 1309897499216000000;
hr = maryln->GetEphemeris1(time, 0, 0);
}
catch(...)
{
}
}
Also, I have cleaned and rebuilt solution numerous times but no luck.

Do not know what may have happened here but I decided to ditch this wrapper DLL and create a new one from scratch. I did not change the C# project I was wrapping just to see which of these two projects was causing the problem. This act alone somehow allowed me to debug each of the APIs exposed in the C# project being wrapped. Using the project debug technique suggested by Hans P, I was able to further debug my wrapper DLL. I gave a big sigh of relieve just being able to see a managed exception. Definitely a step forward.
It turned out that each call to a wrapped API in EphemerisViewController was throwing a manage exception that a dependency could not be found (located assembly manifest does not match loaded assembly....blah..blah.). We all know what causes this.
After cleaning assembly references thereby eliminating the aforementioned error, I could then call my managed DLL again. A day wasted on one hand. A lot learnt on the other hand. Why the original wrapper stopped working is beyond my comprehension but I am glad to let that go. it have have been a combination of namespace corruption and DLL loading issues but who knows.
I was getting ready to ditch COM interop and dive into MFC but boy, i am glad I stuck to my guns. Compared to C#, C++ development sucks as far as i am concerned. For example just being able to catch a general Exception in C# as apposed to the catch(...) equivalent we have for C++ is a serious benefit. All the crazy c++ syntax and head scratching routines to perform simple conversions make my head spin. Not to mention Intellisense, oh intellisense. With a expired Virtual Assist license that reminds me everyday it is laying dormant, and a tight corporate budget, I will stick to C# for a while maybe with thoughts on investigating C++ libraries like Boost when all of this is done, just in case. But boy, I am happy to get back into .NET.
Lesson learnt here for me is: with COM interop, you have to pay close attention to the details!

Related

How to convert an existing customized SwapChainPanel from C++/CX to C++/WinRT

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.

Using Test Doubles with DbEntityEntry and DbPropertyEntry

I am using the new Test Doubles in EF6 as outlined here from MSDN . VS2013 with Moq & nUnit.
All was good until I had to do something like this:
var myFoo = context.Foos.Find(id);
and then:
myFoo.Name = "Bar";
and then :
context.Entry(myFoo).Property("Name").IsModified = true;
At this point is where I get an error:
Additional information: Member 'IsModified' cannot be called for
property 'Name' because the entity of type
'Foo' does not exist in the context. To add an
entity to the context call the Add or Attach method of
DbSet.
Although, When I examine the 'Foos' in the context with an AddWatch I can see all items I Add'ed before running the test. So they are there.
I have created the FakeDbSet (or TestDbSet) from the article. I am putting each FakeDbSet in the FakeContext at the constructor where each one gets initialized. Like this:
Foos = new FakeDbSet<Foo>();
My question is, is it possible to work with the FakeDbSet and the FakeContext with the test doubles scenario in such a way to have access to DbEntityEntry and DBPropertyEntry from the test double? Thanks!
I can see all items I Add'ed before running the test. So they are there.
Effectively, you've only added items to an ObservableCollection. The context.Entry method reaches much deeper than that. It requires a change tracker to be actively involved in adding, modifying and removing entities. If you want to mock this change tracker, the ObjectStateManager (ignoring the fact that it's not designed to be mocked at all), good luck! It's got over 4000 lines of code.
Frankly, I don't understand all these blogs and articles about mocking EF. Only the numerous differences between LINQ to objects and LINQ to entites should be enough to discourage it. These mock contexts and DbSets build an entirely new universe that's a source of bugs in itself. I've decided to do integrations test only when and wherever EF is involved in my code. A working end-to-end test gives me a solid feeling that things are OK. A unit test (faking EF) doesn't. (Others do, don't get me wrong).
But let's assume you'd still like to venture into mocking DbContext.Entry<T>. Too bad, impossible.
The method is not virtual
It returns a DbEntityEntry<T>, a class with an internal constructor, that is a wrapper around an InternalEntityEntry, which is an internal class. And, by the way, DbEntityEntry doesn't implement an interface.
So, to answer your question
is it possible to (...) have access to DbEntityEntry and DBPropertyEntry from the test double?
No, EF's mocking hooks are only very superficial, you'll never even come close to how EF really works.
Just abstract it. If you are working against an interface, when creating your own doubles, put the modified stuff in a seperate method. My interface and implementation (generated by EF, but I altered the template) look like this:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Model
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public interface IOmt
{
DbSet<DatabaseOmtObjectWhatever> DatabaseOmtObjectWhatever { get; set; }
int SaveChanges();
void SetModified(object entity);
void SetAdded(object entity);
}
public partial class Omt : DbContext, IOmt
{
public Omt()
: base("name=Omt")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<DatabaseOmtObjectWhatever> DatabaseOmtObjectWhatever { get; set; }
public void SetModified(object entity)
{
Entry(entity).State = EntityState.Modified;
}
public void SetAdded(object entity)
{
Entry(entity).State = EntityState.Added;
}
}
}

Unity3D embedded Mono with Unity

I've seen plenty of examples of calling static methods in my Unity C# code using C++. I haven't however seen any examples of how to call a single instance's method using C++. i.e rather than
public static void SomeMethod(
{
}
I really want to do:
public void SomeMethod()
{
}
I've managed to make the static implementation work by following some tutorials from but would love to know if the bottom method is possible. I've tried to add a definition for searching a method in a class.
MonoMethod* mono_method_desc_search_in_class (MonoMethodDesc *desc, MonoClass *klass);
But an implementation can't be found with the mono runtime that I was told to use from here: http://www.reigndesign.com/blog/unity-native-plugins-os-x/
Any guidance or knowledge of whether it's possible or how to do it would be appreciated.
Edit:
One other question. If I search for a gameObject, could I then use that to access the instance?
You don't say what platform you're developing for, but for iOS there's the UnitySendMessage function. I believe there are similar implementations for other platforms.
http://docs.unity3d.com/Documentation/Manual/PluginsForIOS.html
Calling C# / JavaScript back from native code
Unity iOS supports limited native-to-managed callback functionality via UnitySendMessage:
UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
The parameter must be a string, so I've used JSON to send more complex data.
Alternatively, everything that inherits from UnityEngine.Object has a GetInstanceID() method, which is guaranteed to be unique. Using this you could have a static method in C# that keeps a dictionary of recipient instances, and native code would always pass an integer ID to refer to the intended recipient.
static Dictionary<int, SomeClass> instanceDict = new Dictionary<...>();
void Awake() {
instanceDict.Add(GetInstanceID(), this);
}
void OnDestroy() {
instanceDict.Remove(GetInstanceID());
}
public static void SomeMethod(int recipientID, float someValue) {
instanceDict[recipientID].SomeMethod(someValue);
}

C++/CLI wrapper not working (LoaderLock exception)

I've made very simple wrapper for unmanaged C++ library (to be used with C#). Wrapper has one unmanaged class and one managed class. Managed class has private member that is of unmanaged class and uses it like that.
I've done very simple setup - I've created wrapper for only one function to see if everything is working. But as soon as I create an instance of wrapper, my application get's exception "LoaderLock was detected" with following message:
DLL 'c:\path\CPPWrapper.dll' is
attempting managed execution inside OS Loader lock. Do not attempt to
run managed code inside a DllMain or image initialization function
since doing so can cause the application to hang.
If I turn off breaking for "LoaderLock" exception, I get "FileLoadException was unhandled":
Could not load file or assembly 'CPPWrapper.dll' or one of its dependencies. Exception from HRESULT: 0xE0434352
Any idea what I am doing wrong and how can I fix this problem?
CPPWrapper.h
// CPPWrapper.h
#pragma once
#include "Native.h"
using namespace System;
namespace CPPWrapper {
public ref class Class1
{
public:
Class1() : mnt(new Native)
{
}
~Class1(void)
{
// call the finalize method
this->!Class1();
}
// Finalize (for garbage collection)
!Class1(void)
{
// Remove unmanaged class
delete mnt;
mnt = NULL;
}
void Napravi()
{
mnt->CreatePK();
}
private:
Native *mnt;
};
}
I found that the correct way to fix this is by adding #pragma unmanaged in the dllmain.c Don't turn off breaking for "LoaderLock" exception.
See Initialization of Mixed Assemblies and scroll down to the DllMain section for details. Basically what is happening is that the project is compiling the DllMain function as managed (MSIL) but it only runs in unmanaged code. This #pragma unmanaged forces the function to be compiled as an unmanaged function.
So my dllmain.c is now:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#pragma unmanaged
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Another potential cause for LoaderLock is initialization of global static objects. In my case, I was compiling a boost::xpressive regex globally and it didn't like doing that when my C++/CLI wrapper was initializing DllMain. I'm not sure why, because it shouldn't have been managed code, but moving it to a function static object fixed it.

Persistence classes in Qt

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....