Dev*_*olo 6 .net c# c++ com interface
由于公司限制不受我的控制,我有以下情况:
定义以下接口的COM库(没有CoClass,只是接口):
[
object,
uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),
dual,
nonextensible,
helpstring("IService Interface"),
pointer_default(unique)
]
IService : IDispatch
{
HRESULT DoSomething();
}
[
object,
uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),
dual,
nonextensible,
helpstring("IProvider Interface"),
pointer_default(unique)
]
IServiceProvider : IDispatch
{
HRESULT Init( IDispatch *sink, VARIANT_BOOL * result );
HRESULT GetService( LONG serviceIndicator, IService ** result );
};
[
uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),
version(1.0),
]
library ServiceLibrary
{
importlib("stdole2.tlb");
interface IService;
interface IServiceProvider;
};
Run Code Online (Sandbox Code Playgroud)
我有一个COM(用W ++编写)实现两个接口并为我们的应用程序提供所述服务.我想一切都很好.
我试图建立一个新的IProvider,并IService在.NET(C#).
我为COM库构建了一个Primary Interop程序集,并实现了以下C#:
[ComVisible( true )]
[Guid( "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" )]
public interface INewService : IService
{
// adds a couple new properties
}
[ComVisible( true )]
[Guid( "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" )]
public class NewService : INewService
{
// implement interface
}
[ComVisible( true )]
[Guid( "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" )]
public interface INewProvider : IServiceProvider
{
// adds nothing, just implements
}
[ComVisible( true )]
[Guid( "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" )]
public class NewProvider : INewProvider
{
// implement interface
}
Run Code Online (Sandbox Code Playgroud)
当我尝试将其放入现有的运行时时,我能够NewProvider从COM(C++)和QueryInterfaceIServiceProvider 创建对象.当我尝试在IServiceProvider上调用方法时,System.ExecutionEngineException抛出a.
我能找到的另一件事是查看#import创建的.tlh文件,显示遗留的COM IExistingProvider类正确显示它是从IServiceProvider派生的.但是,.NET类显示了IDispatch的基础.我不确定这是一个标志,指示,有用,还有别的.
这可能是名称IServiceProvider的问题.检查您是否尚未导入具有相同名称的接口.
当我使用您的IDL创建COM接口库,然后尝试从其他客户端导入它时,我收到警告:
Warning 65 warning C4192: automatically excluding 'IServiceProvider' while importing type library 'ServiceLibrary.dll'
Run Code Online (Sandbox Code Playgroud)
否则,您可以尝试将其重命名为IServiceProvider2.这就是我所做的,一切正常.我正在使用Visual Studio 2008.
如果此代码在您的计算机上正常运行(它在我的计算机上运行正常),则问题可能出在您的实现中.
IDL:
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;
};
Run Code Online (Sandbox Code Playgroud)
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3161 次 |
| 最近记录: |