我需要使一段C#代碼通過COM與各種實現進行交互。在C#中爲客戶端和服務器使用C++ COM接口
爲了讓該集成的用戶更輕鬆,我將交互的接口包含在IDL中(作爲相關現有DLL的一部分,但沒有coclass或實現),然後通過運行Tlbimp創建類型定義。
我實現了我的C#,基於Windows註冊表信息創建COM對象,並將對象轉換爲我需要的接口。
然後我在一個單獨的項目中創建了接口的C#實現並註冊它。 主程序正確創建了測試COM對象,但未能將其轉換爲接口(使用C#'獲取空對象作爲',獲取顯式強制轉換的InvalidCastException)。
有人可以建議爲什麼接口不被識別爲由測試對象實現嗎?
這是在IDL接口defition(編譯的C++中VS 2005):
[
object,
uuid(B60C546F-EE91-48a2-A352-CFC36E613CB7),
dual,
nonextensible,
helpstring("IScriptGenerator Interface"),
pointer_default(unique)
]
interface IScriptGenerator : IDispatch{
[helpstring("Init the Script generator")]
HRESULT Init();
[helpstring("General purpose error reporting")]
HRESULT GetLastError([out] BSTR *Error);
};
這是通過TLBIMP爲C#創建的存根:
[TypeLibType(4288)]
[Guid("B60C546F-EE91-48A2-A352-CFC36E613CB7")]
public interface IScriptGenerator
{
[DispId(1610743813)]
void GetLastError(out string Error);
[DispId(1610743808)]
void Init();
}
這是主要的部C#代碼,創建它的進程id一個COM對象,並將其投射到IScriptGenerator接口:
public ScriptGenerator(string GUID)
{
Type comType = Type.GetTypeFromProgID(GUID);
object comObj = null;
if (comType != null)
{
try
{
comObj = Activator.CreateInstance(comType);
}
catch (Exception ex)
{
Debug.Fail("Cannot create the script generator COM object due to the following exception: " + ex, ex.Message + "\n" + ex.StackTrace);
throw ex;
}
}
else
throw new ArgumentException("The GUID does not match a registetred COM object", "GUID");
m_internalGenerator = comObj as IScriptGenerator;
if (m_internalGenerator == null)
{
Debug.Fail("The script generator doesn't support the required interface - IScriptGenerator");
throw new InvalidCastException("The script generator with the GUID " + GUID + " doesn't support the required interface - IScriptGenerator");
}
}
和TH是在執行C#代碼,以測試它的工作(這不是):
[Guid("EB46E31F-0961-4179-8A56-3895DDF2884E"),
ProgId("ScriptGeneratorExample.ScriptGenerator"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(SOAAPIOLELib.IScriptGeneratorCallback))]
public class ScriptGenerator : IScriptGenerator
{
public void GetLastError(out string Error)
{
throw new NotImplementedException();
}
public void Init()
{
// nothing to do
}
}