Has anybody tried to use C++/winrt to create Win32 COM objects? The C++/winrt docs document that consuming them is possible and of course creating "new" UWP COM objects. I was wondering if for some simple scenario's one could use the C++/winrt headers instead of ATL to generate some simple COM objects.
You can write a COM component with C++/WinRT. Here’s an example of a COM executable server but the principles and techniques are much the same for a DLL.
https://gist.github.com/kennykerr/d983767262118ae0366ef1ec282e428a
For a DLL you just want to make sure you export an implementation of DllGetClassObject and DllCanUnloadNow. Otherwise, its just like any other DLL and you can use the winrt::implements class template to implement the various classes and factories.
I'm trying to use a 3rd party DLL (WinSCP .NET assembly) in Dolphin 6.1b2. I've registered the DLL and generated a TypeLib in Windows 7.
In Dolphin I successfully used the component wizard to generate the interfaces but when I try to register the control and TypeLib I get errors. On the registering the control I get
WinSCPnet.dll was loaded but DllRegisterServer entry point could not be found.
Does anyone have any idea why it's failing? I have also asked the author of the DLL and he's leaning toward a Dolphin problem since the registration worked in Windows.
The DLL is a .NET assembly, import the generated TLB.
Downloaded ".NET assembly/automation package" from: https://winscp.net/eng/download.php
Unpacked, registered as per included readme_automation.txt.
See also Downloading and Installing WinSCP .NET Assembly
Started fresh Dolphin, imported the .tlb, generated with WinSCP prefix (so the classes wouldn't start with _).
Opened workspace, imported the WinSCP_Constants Pool, converted start of the C# example (https://winscp.net/eng/docs/library#example):
opts := WinSCP_SessionOptions new
protocol: Protocol_Sftp;
hostName = 'example.com';
userName: 'user';
password: 'mypassword';
sshHostKeyFingerprint: 'ssh-rsa 2048 ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff';
yourself.
Got working object back ...
EDIT: Your WinSCP forums notion "in order to use it within dolphin you need to have its tools register the dll and tlib" is wrong. The COM "source" needs to be registered only once (In case of "old-school" COM server, you can either use regsvr32 or dolphin - both does the same; in case of .NET assembly you have to use the .NET incantation). Only thing really needed on dolphin side is to import previously registered library.
If there is .TLB, I'd go for .TLB, otherwise try my luck with .DLL. Sadly, for some standard COM interfaces Microsoft never made typelibs available, so it's even worse there (use C/C++, or create struct/interface tables by hand).
Edit 2 - further questions:
1) can you explain the relationship between the typelib and the library class which "i create" ( i.e. dolphin tutorial in help)
Dolphin creates smalltalk classes to mirror the COM types / structures. You use these to instantiate COM types from Smalltalk, call their methods, pass them (and also primitive types such as strings, integers, ...) as arguments and get Smalltalk types for returned values (Dolphin does all the conversions for you, so you can +- forget you are calling foreign code).
2) an example of the method you implemented mapping the library class to the winscp interface.
I implemented nothing, I just used the generated wrapper (in background, WinSCP COM object - SessionOptions - got created, and had some properties set).
basically, i just said:
var opts = new WinSCP.SessionOptions().
opts.Protocol = Protocol.Sftp;
opts.HostName = .........
Just look at WinSCP Automation documentation / examples, and then convert it to smalltalk-speak (and hopefully, it should auto-magically work ;-).
3) where are the smalltalk methods protocol:, hostName:, etc defined? i searched the image and they are not there. how did you know to use those method names?
Since SessionOptions (represented by [PREFIX]_SessionOptions class in Dolphin) is an IDispatch interface (subclass of IDispatch in Dolphin), all the method calls are dynamic in nature. You just do the right things (& catch possible failures at necessary granularity), and it will "just work (tm)".
Smalltalk sibbling is the #doesNotUnderstand: aMessage method.
It is now well known how to make interface call to a DLL-implemented COM object in the registration-free environment. The question is the opposite:
How to make interface call from a DLL to a COM object implemented in EXE? Which manifests and which manifest sections should be used?
EDIT: May be it was not quite clear, but I meant in-process call. I want to call an object in the same process, but implemented in EXE rather than in DLL.
EDIT2: OK, I see things goes complicated, so I must explain the original problem. A C++ application implements IApplication interface and keeps pointer to it as a member. This member is returned by a public method accessible from anywhere by means of AfxGetApp().
There is also a mechanism allowing any customer to add his own C# "plugin" DLLs to our application. For such DLLs the IApplication interface is a key access point to the application's features. But these DLLs have no access to the main application's object.
To solve the problem, I added an auxiliary "ICreateApplication" object, which returns the original IApplication pointer. Any "plugin" DLL may create this auxiliary object and obtain from it the required interface. I implemented this object in some arbitrarily chosen DLL, and equipped it with necessary manifests.
This solution works well, but this "arbitrary choice" bothers me. I wonder, is there a possibility to implement "ICreateApplication" in the application object?
Suppose we have COM DLL registered in system registry. Now the requirement is to call that com dll functions in quartz.net.
I am thinking to make an auxiliary class that will contain implemented Execute method and using job data map I will call appropriate function in registered COM DLL. This is the way i am thinking to proceed.
Is there any other way that is easy and provide more flexibility.
I searched hard, but was unable to grasp the whole idea. Can anyone tell me:
What COM actually is?
How do GUIDs work, and how are they used by COM?
How does COM resolve the issues of different DLL versions.
Or at least, point me to a good article somewhere that explains these concepts?
Thanks!
COM is "Component Object Model". It is one of the first technologies designed to allow "binary reuse" of components... Originally, it was the rewrite of what was, in Microsoft Office circa 1988-1992 time frame, referred to as Dynamic Data Exchange (DDE), a technology designed to allow the various Office applications to talk to one another. The first attempt to rewrite it was called OLE-Automation (Object Linking and Embedding). But when they got done they renamed it to COM.
How it works:
Essentially, before COM, when a client component wanted to use a component (written as a C++ library), it had to be compiled WITH the library, so it could know exactly how many bytes into the compiled binary file to find each method or function call.
With COM, there is a defined mechanism as to how these methods will be structured, and then the compiler produces a separate file (called a type library or an Interface Definition Language (IDL) file, that contains all this function offset data.
Then, as a user of the component, you have to "register" it, which writes all this information (Keyed off of GUIDs) into the OS Registry, where any client app can access it, and by reading the data from the registry, it can know where in the binary file to find each method or class entry point.
Your question is a little large for a full explanation here. A quick high-level introduction to COM can be found in the book Understanding ActiveX and OLE. A more detailed but still introductory introduction is Inside COM. The best book on the subject is Don Box's Essential COM.
A couple of quick answers:
COM is a binary interface standard for objects. It allows various programs to write to interfaces without all having to have been written in the same langauge with the same compiler. There are also related services available.
GUIDs are globally unique numbers that COM uses to identify interfaces.
COM doesn't resolve different DLL version problems. It only allows a single DLL to be registered for each GUID.
COM enables reusable software. Like building blocks, you can create COM objects (or now Assemblies in .NET) to provide functionality to a larger piece of software. I have used COM to provide DB integration for Excel and MS BizTalk. Software like MS BizTalk use COM/Assemblies to extend the processing capabilities of a standard process; you can insert a COM into the message workflow to do more processing than is implemented by Microsoft. COM also allows use of Component Services providing built in object pooling, security, and control interface.
Wikipedia has a good definition of GUID. Note that Microsoft has a formatting that is not necessarly used in the rest of development community.
COM by itself does not resolve DLL version issues. It enables you to extend software incrementally if you use the COM versioning capability. So if you have an application that uses a COM to convert XML to Text (for example) and you want to enhance, you can create a new version (2.0) which you can roll-out slowly as you update the source application to use the new COM. This way you could (if need be) have a switch statement that can still use the old COM if required by system limitations, or use the new one (they would be different DLLs).
COM is a lot of different things. I recommend Don Box's book, Essential COM as a good way to learn.
At a bare minimum, a COM object is an object that exposes a single interface, IUnknown. This interface has 3 methods, AddRef, Release, and QueryInterface. AddRef/Release enables the object to be reference counted, and automatically deleted when the last reference is released. QueryInterface allows you to interrogate the object for other interfaces it supports.
Most COM objects are discoverable. They are registered in the registry under HKEY_CLASSES_ROOT with an identifying GUID, called a CLSID (class ID). This enables you to call CoCreateInstance to create an instance of a registered object if you know a GUID. You can also query the registry via a COM API for the CLSID that backs a ProgId (program id), which is a string that identifies the object.
Many COM objects have typelibs that specify the interfaces and methods the object supports, as well as IDispatch which has a method, Invoke, that allows you to dynamically call methods on the object. This enables the object to be used from scripting languages that don't support strong typing.
Some objects support being run in a different process, on a different thread, or on a different machine. COM supports marshalling for these types of objects. If possible, a standard marshaller can use the object's typelib to marshal calls to the object, but custom marshallers can be provided as well.
And there's a whole lot more to COM objects, I'm barely scratching the surface.
10,000 foot view:
COM is the communication mechanism for software components. Example, you can interact with COM interfaces (COM interop in .NET) to use functionality not exposed through a common interface (.NET assembly).
GUIDs are explained fairly decent on Wikipedia http://en.wikipedia.org/wiki/Globally_Unique_Identifier
I always understood LIB files to be object files for the C++ linker. They contain the code for all objects in a cpp file. The compiler optimizes when it links disregarding portions of the object file that it doesn't need.
Someone please clarify as I am sure I butchered some of this.
COM is Microsoft's Component Object Model, a binary-compatible interface for programs written in various languages to interoperate with each other. It is the "evolutionary step" between the OLE and .NET technologies.
If you want to learn about COM from the C++ perspective, take a look at Don Box's Essential COM, or ATL Internals by Rector and Sells.
The group microsoft.public.vc.atl is probably the best place to ask questions you can't get answers for here. It's primarily an ATL newsgroup, but it seems to be the newsgroup with the most traffic for general COM questions as well. (just be prepared for the usual newsgroup curtness & impatience)
COM is a method to develop software components, small binary exe, that provides services for applications, OS and other components. Developing custom COM comnponent is like developing Object oriented API. GUID is a Global unique ID and used to identify a COM component uniquely.
You can refer a very good book by Dale Rogerson for more details. Inside COM