我确信我的问题的答案是本论坛上已有的许多主题的组合。也许你可以帮我把各个部分放在一起。
所以我的挑战是,我有一些C ++代码实现了这样的接口:
interface ItsSupplier : IDispatch {
[propget, id(1), helpstring("property name") HRESULT Name([out, retval] BSTR* pVal);
}
实现此接口的DLL是第三方软件中的可用插件。 我想用.NET编写一个插件。 由于使用插件的软件不是.NET,我认为DLL必须是COM对象。
以下是我在.NET中的使用方法。
[Guid("xxxx")]
public interface ItsSupplier {
[DispId(1)]
[return: MarshalAs(UnmanagedType.Bstr)]
string Name { get; }
}
[Guid("xxxx"),
ClassInterface(ClassInterfaceType.AutoDispatch),
ComSourceInterfaces(typeof(ItsSupplier))]
public class SupplierClass : ItsSupplier
{
public string { get { return "someName"; } }
}
}
在项目设置下,我检查了“注册COM interorp”。
构建后我运行“regasm testDll.dll”
我的问题是......
这是自己定义ItsSupplier界面的正确方法吗?我的意思是,这是第三方软件所期望的接口,所以它必须在其他地方被引用吗?
对于COM互操作部分,我做得对吗?
我希望我能解释这一点:)
干杯 /托马斯
---------------- HANS回应后的编辑------------------------
当我构建tlb文件并在Oleview中查看原始版本和我的版本时,这就是我得到的。
这是原始界面插件在Oleview中的样子:
[
odl,
uuid(370B4079-40BB-47C9-B797-33B3B5422685),
helpstring("ItsSupplier Interface"),
dual,
oleautomation
]
interface ItsSupplier : IDispatch {
以下是我的看法:
[
odl,
uuid(370B4079-40BB-47C9-B797-33B3B5422685),
version(1.0),
dual,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "COMDLL.ItsSupplier")
]
interface COMDLL_ItsSupplier : IDispatch {
“COMDLL”是我的visual studio项目的名称。你认为这很重要吗?
/托马斯
答案 0 :(得分:3)
不,很多微妙的错误会让你陷入困境。首先,c ++接口声明了一个双接口,通过IDispatch支持早期绑定和后期绑定。您必须使用.NET中的[InterfaceType]属性来获得相同的内容:
[ComVisible(true)]
[Guid("xxxx")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ItsSupplier {
[DispId(1)]
string Name { get; }
}
请务必使用完全相同的guid,它在您的代码段中不可见。 [MarshalAs]属性是不必要的,字符串已经作为BSTR编组。
接下来是班级。您不想要公开类实现。这迫使客户端代码也要注意System.Object,它是所有.NET类的基类。它将出现在类型库中。使用[ComSourceInterfaces]不正确,应该只应用于事件的调度接口。
[ComVisible(true)]
[Guid("xxxx")]
[ClassInterface(ClassInterfaceType.None)]
public class SupplierClass : ItsSupplier
{
public string Name {
get { return "someName"; }
}
}
再次使用与IDL文件中使用的完全相同的guid。接下来是注册。使用“注册COM互操作”选项很好但是不再次运行Regasm.exe。你会搞砸注册的。如果您更喜欢手动注册,那么请始终使用/ codebase选项,这样就不必在GAC中安装程序集。
确保一切正确的最终检查是使用Tlbexp.exe创建类型库,并使用Oleview.exe,File + View Typelib查看它。它应该与您的IDL完全匹配。