我有几个建议。首先,为您在COM中使用的任何东西创建一个接口,即使它只是一个普通的DTO,没有方法,只有属性。COM喜欢接口。它非常喜欢接口,以至于您在COM中接触到的所有内容都是接口。
另一个建议是,在您在COM中接触到的任何东西上放置GuidAttribute。这将确保在使用COM注册托管程序集时,您的注册表不会出现问题。COM比接口更喜欢GUID,并且如果一个接口注册到多个GUID上,COM很容易感到困惑,如果您不在代码中硬编码接口GUID,则可能会发生这种情况。具体类也需要一个GUIDAttribute。
我知道这很糟糕,但这就是为什么微软正在努力让人们远离使用COM。
话虽如此,您可能希望像这样使用C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
[ComVisible(true)]
[Guid("1CEB24F2-BF13-417F-B5BC-DB8E82A56EAE")]
public interface ITestEntity1
{
bool Thing { get; set; }
}
[ComVisible(true)]
[Guid("C8B5A7C2-F67C-4271-A762-3642754F2233")]
public class TestEntity1 : ITestEntity1
{
public bool Thing { get; set; }
}
[ComVisible(true)]
[Guid("8904A7EC-D865-4533-91EC-1F68524651D0")]
public interface ITestEntity2
{
string Description { get; set; }
}
[ComVisible(true)]
[Guid("668EE2E8-5A60-468B-8689-D9327090AA44")]
public class TestEntity2 : ITestEntity2
{
public string Description { get; set; }
}
[ComVisible(true)]
[Guid("2791082F-F505-49C4-8952-80C174E4FE96")]
public interface ITestGateway
{
void DoSomething(string a, [MarshalAs(UnmanagedType.Interface)]object comInputValue);
}
[ComVisible(true)]
[Guid("C3D079F3-7869-4B3E-A742-263775C6EA63")]
public class TestGateway : ITestGateway
{
public void DoSomething(string a, object comInputValue)
{
if (a == "yes")
{
var entity = (TestEntity1)comInputValue;
}
else
{
var entity = (TestEntity2) comInputValue;
}
if(comInputValue is TestEntity1)
{
}
else if(comInputValue is TestEntity2)
{
}
else
{
}
}
}
}
以下的C++代码可以实现该功能:
以下的C++代码可以实现该功能:
#include "stdafx.h"
#import <mscorlib.tlb> raw_interfaces_only
#import "..\Debug\ClassLibrary1.tlb" no_namespace named_guids
int _tmain(int argc, _TCHAR* argv[])
{
ITestGateway* test = NULL;
char buffer[50];
gets(buffer);
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_TestGateway,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITestGateway,
reinterpret_cast<void**>(&test));
if(FAILED(hr)) {
printf("Couldn't create the instance!... 0x%x\n", hr);
gets(buffer);
} else {
_bstr_t someString("yes");
ITestEntity1* testEntity1 = NULL;
HRESULT hr = CoCreateInstance(CLSID_TestEntity1,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITestEntity1,
reinterpret_cast<void**>(&testEntity1));
if(FAILED(hr)) {
printf("Entity was not created!... 0x%x\n", hr);
gets(buffer);
return 0;
}
testEntity1->PutThing(VARIANT_FALSE);
test->DoSomething(someString, testEntity1);
printf("Something was done.");
testEntity1->Release();
}
test->Release();
return 0;
}