I need to implement a bare-bones COM object in straight C++ (no ATL) that is used by a legacy web application to check that my application exists. The web application does something like this (JavaScript):
var object = new ActiveXObject("My.Application");
I want to ensure that the above succeeds but thats all I need to do - I do not need to implement any methods/properties on this object as they are never called.
Obviously I need to ensure that my object is registered by adding the necessary registry settings, etc. My application is a DLL so I guess I also need to implement a handful of exported functions (DllRegisterServer, DllUnregisterServer, DllCanUnloadNow and, the one that has to so something, DllGetClassObject).
I'm pretty sure that simply returning S_OK from DllGetClassObject won't cut it.
How can I go about implementing a basic interface without using ATL? I am using the MS compiler if that helps.
It's not sufficient to build a bare-bones COM object. For starters, that would be so bare-bones that there's no name associated with it. You've already discovered that you need an object factory, too.
So, yes, implement DllGetClassObject. You'll have to check the input rclsid argument. This is an interface identifier. If you don't recognize it, return CLASS_E_CLASSNOTAVAILABLE. Apparently, because of hackerish approaches (like the unconditional S_OK you suggested) Microsoft now passes at least one invalid class ID.. If you lie, and claim you can do it, Windows will not believe anyhting else you say.
So, what interfaces should you claim? Obviously IUnknown - it's the very root of the system. The most bare-bone COM object doesn't do anything else. You need more interfaces, though - the web app is asking for an ActiveX object. That requires more interfaces. Possibly the easiest approach would be to just see what Windows is asking for. I suspect you'll need at least IDispatch.
Next, you'll have to implement a few methods. "Wait", you may say, "they're not called". Well, IDispatch is a kind of meta-interface for scripting langauges. It's used to enumerate which methods are available. Hence, your IDispatch interface should support such enumeration as well, even though it would return zero scriptable methods.
There's a lot more detail, but this should already be sufficient to help convince you to use ATL and grab its ActiveX code. That's going to be far more complete than anything I can list here.
There is nothing bare-bones about a COM server that supports late binding from Javascript running inside IE. If you don't know how to implement DllGetClassObject() then you need all the help you can get. You get a lot of help from ATL and the wizards built into Visual Studio. The vast majority of the fugly plumbing code is auto-generated, including those 4 exports. And IDispatch, the interface that the Javascript needs.
Start the project with the ATL + ATL Project template. The defaults are good. Right-click the project, Add, Class and select ATL + ATL Simple Object. Switch to Class View, locate your interface type and right-click it to add methods and properties.
Related
I've been developing for some time. And these beasts appear from time to time in MFC, wxWidgets code, and yet I can't find any info on what they do exactly.
As I understand, they appeared before dynamic_cast was integrated into core C++. And the purpose, is to allow for object creation on the fly, and runtime dynamic casts.
But this is where all the information I found, ends.
I've run into some sample code that uses DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS within a DLL, and that is used for exported classes. And this structure confuses me.
Why is it done this way? Is that a plugin based approach, where you call LoadLibrary and then call the CreateDynamicClass to get a pointer which can be casted to the needed type?
Does the DECLARE/IMPLEMENT_DYNAMIC work over DLL boundaries? Since even class is not so safe to DLLEXPORT, and here we have a custom RTTI table in addition to existing problems.
Is it possible to derive my class from a DYNAMIC_CLASS from another DLL, how would it work?
Can anyone please explain me what these things are for, or where I can find more than a two sentences on a topic?
This stuff appends addional type information to your class, which allows to RTTI in runtime-independent manner, possibility of having factories to create your classes and many other things. You can find similar approach at COM, QMetaObject, etc
Have you looked at the definitions of DECLARE/IMPLEMENT_DYNAMIC?
In the MS world, all uppercase usually denotes a macro, so you can just look up the definition and try to work out what it's doing from there. If you're in Visual Studio, there's a key you can hit to jump to the definition - see what it says, and look that up and try to work from there.
I'm writing an NPAPI plugin in C++ on Windows. When my plugin's instantiated, I want to pass it some private data from my main application (specifically, I want to pass it a pointer to a C++ object). There doesn't seem to be a mechanism to do this. Am I missing something? I can't simply create my object in the plugin instance, since it's meant to exist outside of the scope of the plugin instance and persists even when the plugin instance is destroyed.
Edit:
I'm using an embedded plugin in C++ via CEF. This means that my code is essentially the browser and the plugin. Obviously, this isn't the way standard NPAPI plugins behave, so this is probably not something that's supported by NPAPI itself.
You can't pass a C++ object to javascript; what you can do is pass an NPObject that is also a C++ object and exposes things through the NPRuntime interface.
See http://npapi.com/tutorial3 for more information.
You may also want to look at the FireBreath framework, which greatly simplifies things like this.
Edit: it seems I misunderstood your question. What you want is to be able to store data linked to a plugin instance. What you need is the NPP that is given to you when your plugin is created; the NPP has two members, ndata (netscape data) and pdata (plugin data). The pdata pointer is yours to control -- you can set it to point to any arbitrary value that you want, and then cast it back to the real type whenever you want to use it. Be sure to cast it back and delete it on NPP_Destroy, of course. I usually create a struct to keep a few pieces of information in it. FireBreath uses this and sends all plugin calls into a Plugin object instance so that you can act as though it were a normal object.
Relevant code example from FireBreath:
https://github.com/firebreath/FireBreath/blob/master/src/NpapiCore/NpapiPluginModule_NPP.cpp#L145
Pay particular attention to NPP_New and NPP_Destroy; also pay particular attention to how the pdata member of the NPP is used.
This is also discussed in http://npapi.com/tutorial2
There is no way to do this via NPAPI, since the concept doesn't make sense in NPAPI terms. Even if you hack something up that passes a raw pointer around, that assumes everything is running in one process, so if CEF switches to the multi-process approach Chromium is designed around, the hack would break.
You would be better off pretending they are different processes, and using some non-NPAPI method of sharing what you need to between the main application and the plugin.
I have a simple SDI app which works pretty well.
Lately I decided to make use some of functions, exported by a DLL.
All those DLL functions work with a static memory buffer (which the app must define and use in the function calls) .
Fact is, some DLL functions should be called when specific things happen in the View.
I am not sure how I should handle calling of the DLL functions. Should the MainFrame, the Document and the View all have access to them (and hence to the memory buffer) ?
Or should they message the app to make the function calls instead ?
Define "correct" :)
First of all, I think you will be better off if you wrap all the calls to the DLL and put them in one place. Then it doesn't really matter which one calls the DLL (interface wise that is). However, it's good practice to let only one part of the system know about the DLL and use that interface. In this case it depends on what the DLL is actually doing, i.e. what kind of abstraction layer it aims to work on. If it's data related to the Document, it's the Document that should take care of the communication. It could even be used by the View, if the DLL is doing View-related stuff. If the DLL is doing application related stuff it should belong to the app.
Just ask yourself the question what the DLL is doing, i.e. what kind of role it has in your design and let that decide.
I have generated an ATL COM object using VS2008 and the code contains references to a definition called _MERGE_PROXYSTUB (because I chose the 'Merge proxy/stub' option when I initially ran the wizard.)
What is the point of a proxy/stub? If I don't select the the merge option then I get a separate MyControlPS.DLL instead - when would this ever be used?
FWIW the control seems to register and work fine if I remove all the code surrounded by the _MERGE_PROXYSTUB defines. A debug build doesn't even define _MERGE_PROXYSTUB and it still works OK.
So, can I do without a proxy/stub?
You need a proxy/stub if you want your COM object to be called from an application using a different threading model than your COM object.
For example, we have a plug in that gets loaded by an application that uses a particular threading model (can't remember which), but our COM object is multithreaded apartment (MTA) - so the the proxy/stub is required to marshall the data between the objects when a function call is made, while still adhering to the rules of the threading model.
If these rules are broken, then COM will either throw an exception or return a failure HRESULT such as RPC_E_WRONG_THREAD
If you don't check the merge proxy/stub option, then visual studio produces a seperate project for the proxy/stubs which get build into a seperate dll. This makes things more difficult for deployment if they are required, but you can basically just ignore them if you are not affected by threading model issues.
So you can do without proxy/stubs if the application calling the COM object is using the same threading model as your object
Larry Osterman provides a readable introduction to threading models on his blog.
Also, if your interfaces contain only type-library-friendly types (BSTR, VARIANT, etc) and appear in the library block of your IDL, you can elect to have them "type library marshalled" meaning that a system-provided proxy/stub uses the meta-data from the type library.
When interfaces are put inside the library block, and DllRegisterServer is customized to register the type library (pass TRUE to XxxModule::DllRegisterServer, if I recall correctly) your interfaces will be marshalled by the system, if necessary, as described by John Sibly.
At that point, the proxy/stub isn't even used, so _MERGE_PROXYSTUB has no effect.
I'm new to COM programming. I've got a COM object (and associated IClassFactory) all ready to go, but I can't quite figure out how to go about registering the resulting DLL for use by other programs. The number of GUIDs I need to sling around is also unclear to me.
The COM object I'm trying to register implements the IAudioSessionEvents interface.
I have come across the DllRegisterServer and DllUnregisterServer functions, but I haven't found any clear demonstrations of their usage. What keys do they deal with, how are they invoked, by what and when, etc.?
Thanks,
-Kevin Montrose
I'm not sure from this post whether you are implementing or consuming the DLL that supports IAudioSessionEvents. If you're consuming this DLL, then you can register the component using the comment line utility regsvr32. To register use:
regsvr32
To unregister:
regsvr32 /u
regsvr32 should be on your path, so this command will work from any directory.
If you are implementing the DLL in question, then you must provide an implementaion of the DllRegisterServer and DllUnRegisterServer functions. These functions must set up and clean up registry entries for your component. The purpose of the registry entries is to provide a ProgID, map it to a CLSID, and provid interface ID for the interfaces that the component supports. For example, the interface ID for IAudioSessionEvent. If you're implementing the DLL, you'll have to provide code to perform all of these tasks.
Note: these functions are called by regsvr32 in order to register the component.
If very unusual to actually write this code, generally you'll want to use a framework like ATL, which takes care of the busywork for you. It is a good exercise to write this code at least once if you really want to know COM from the ground up.
You need one GUID for every class you expose to COM and one GUID for every new interface you introduce and want to make available through COM.
DllRegisterServer/DllUnregister server are called when you use regsvr32 utility (ships with Windows) to register your COM-exposed classes. It adds/removes keys to HKCR/CLSID branch for every class you expose to COM. These keys are used by CoCreateInstance() to find out which DLL to load for creating an instance of a class with a given GUID.
If you use ATL or something similar usually don't need to completely implement DllRegisterServer/DllUnRegisterServer but use the implementation provided with the library.
Quite often the easiest way to implement self registration is to use the ATL server classes, have a global variable that derives from CComModule (or some other similar class) and define a COM_MAP in your module. You then ask the com module to handle the registration based on the .rgs files that you have added to your project.