So, it's been a looong time since I've done Win32 and COM stuff... That's actually what I did a lot of in the late 90's before moving on to Java & .NET, but anyways after some time I think I figured out what it is you need to do. Now, keep in mind this may not be following best practices, but it seems to be working in some tests I tried.
First, you need to define your COM interfaces. You can do this in IDL:
Code:
[
uuid(D13B66C0-458F-478C-94EA-703BC1F559D6),
version(1.0)
]
library Plugins
{
import "oaidl.idl";
import "ocidl.idl";
importlib("stdole2.tlb");
interface ITuner;
[
uuid(77C2AC04-AAA4-4B0F-BE31-59B2306B5E68)
]
interface ITuner : IUnknown
{
HRESULT TuneChannel([in] double channel);
HRESULT CurrentChannel([out, retval] double* channel);
};
};
Then, create a typelib using midl:
Code:
midl Plugins.ild /tlb Plugins.tlb
Then, if you're creating COM objects in C++ or VB6 you're done. If you (or 3rd parties) want to develop .NET plugins, you need to create an interop DLL from that typelib:
Code:
tlbimp Plugins.tlb /keyfile:mykey.snk /out:Plugins.cs
We also need to install this assembly in the GAC so all COM objects can reference it and register it:
Code:
gacutil /i Plugins.dll
regasm Plugins.dll
Now, create a project referencing this assembly, implement a concrete impl using the ITuner interface, make sure the ComVisible attribute is true, sign the assembly, and build. For example:
Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Plugins;
[assembly: ComVisible(true)]
[assembly: Guid("631717cd-91b3-4b4e-a8f4-5278111bd7c5")]
namespace MySamplePlugins
{
[ClassInterface(ClassInterfaceType.None)]
[Guid("540287F0-D790-4AB5-9C42-65D19DEDF99A")]
public class SampleTuner : ITuner
{
private double channel = 101.1;
public void TuneChannel(double channel)
{
Trace.TraceInformation("Tuning channel {0}", channel);
this.channel = channel;
}
public double CurrentChannel()
{
return channel;
}
}
}
Code:
gacutil /i MySamplePlugins.dll
regasm MySamplePlugins.dll
OK! Now, in your Win32 app you just need to use the COM interfaces you defined in the IDL:
Code:
#include "stdafx.h"
#import "../Plugins.Interfaces/Plugins.tlb" named_guids raw_interfaces_only
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
Plugins::ITunerPtr pTuner;
double channel = 103.5;
HRESULT hresult = pTuner.CreateInstance("MySamplePlugins.SampleTuner");
if (hresult == S_OK)
{
hresult = pTuner->TuneChannel(channel);
channel = 0.0;
hresult = pTuner->CurrentChannel(&channel);
printf("Tuned to channel %f\n", channel);
}
CoUninitialize();
return 0;
}
Hope that helps!!! Like I said, some of this may be better in another way, but this worked for me. Gave me something to think about on this snow day! ;)