名称IServiceProvider可能有问题。检查您是否尚未导入具有相同名称的接口。
当我使用您的 IDL 创建 COM 接口库,然后尝试从另一个客户端导入它时,我收到警告:
Warning 65 warning C4192: automatically excluding 'IServiceProvider' while importing type library 'ServiceLibrary.dll'
否则,您可以尝试将其重命名为 IServiceProvider2。这就是我所做的,一切正常。我正在使用 Visual Studio 2008。
如果此代码在您的机器上正常运行(它在我的机器上运行良好),那么问题可能出在您的实现中。
身份证:
import "oaidl.idl";
[
object,
uuid(9219CC5B-31CC-4868-A1DE-E18300F73C43),
dual,
nonextensible,
helpstring("IService Interface"),
pointer_default(unique)
]
interface IService : IDispatch
{
HRESULT DoSomething(void);
}
[
object,
uuid(9219CC5B-31CC-4868-A1DE-E18300F73C44),
dual,
nonextensible,
helpstring("IProvider Interface"),
pointer_default(unique)
]
interface IServiceProvider2 : IDispatch
{
HRESULT Init( IDispatch *sink, VARIANT_BOOL * result );
HRESULT GetService( LONG serviceIndicator, IService ** result );
};
[
uuid(9219CC5B-31CC-4868-A1DE-E18300F73C45),
version(1.0),
]
library ServiceLibrary
{
importlib("stdole2.tlb");
interface IService;
interface IServiceProvider2;
};
C#:
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ServiceLibrary;
using IServiceProvider=ServiceLibrary.IServiceProvider2;
namespace COMInterfaceTester
{
[ComVisible(true)]
[Guid("2B9D06B9-EB59-435e-B3FF-B891C63108B2")]
public interface INewService : IService
{
string ServiceName { get; }
}
[ComVisible(true)]
[Guid("2B9D06B9-EB59-435e-B3FF-B891C63108B3")]
public class NewService : INewService
{
public string _name;
public NewService(string name)
{
_name = name;
}
// implement interface
#region IService Members
public void DoSomething()
{
MessageBox.Show("NewService.DoSomething");
}
#endregion
public string ServiceName
{
get { return _name; }
}
}
[ComVisible(true)]
[Guid("2B9D06B9-EB59-435e-B3FF-B891C63108B4")]
public interface INewProvider : IServiceProvider
{
// adds nothing, just implements
}
[ComVisible(true)]
[Guid("2B9D06B9-EB59-435e-B3FF-B891C63108B5")]
public class NewProvider : INewProvider
{
// implement interface
public void Init(object sink, ref bool result)
{
MessageBox.Show("NewProvider.Init");
}
public void GetService(int serviceIndicator, ref IService result)
{
result = new NewService("FooBar");
MessageBox.Show("NewProvider.GetService");
}
}
}
C++ 客户端:
#include "stdafx.h"
#include <iostream>
#include <atlbase.h>
#import "COMInterfaceTester.tlb" raw_interfaces_only
#import "ServiceLibrary.dll" raw_interfaces_only
using std::cout;
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL); //Initialize all COM Components
COMInterfaceTester::INewProviderPtr pNewProvider(__uuidof(COMInterfaceTester::NewProvider));
ServiceLibrary::IServiceProvider2 *pNewProviderPtr;
HRESULT hr = pNewProvider.QueryInterface(__uuidof(ServiceLibrary::IServiceProvider2), (void**)&pNewProviderPtr);
if(SUCCEEDED(hr))
{
VARIANT_BOOL result = VARIANT_FALSE;
int *p = NULL;
hr = pNewProviderPtr->Init((IDispatch*)p, &result);
if (FAILED(hr))
{
cout << "Failed to call Init";
}
ServiceLibrary::IService *pService = NULL;
hr = pNewProviderPtr->GetService(0, &pService);
if (FAILED(hr))
{
cout << "Failed to call GetService";
}
else
{
COMInterfaceTester::INewService* pNewService = NULL;
hr = pService->QueryInterface(__uuidof(COMInterfaceTester::INewService), (void**)&pNewService);
if (SUCCEEDED(hr))
{
CComBSTR serviceName;
pNewService->get_ServiceName(&serviceName);
if (serviceName == "FooBar")
{
pService->DoSomething();
}
else
cout << "Unexpected service";
pNewService->Release();
}
pService->Release();
}
pNewProviderPtr->Release();
}
else
cout << "Failed to query for IServiceProvider2";
pNewProvider.Release();
CoUninitialize (); //DeInitialize all COM Components
}