benjaminemanuel13 Ответов: 1

Потребление com-компонента idispatch в C#


Я написал COM - компонент на C++ (6.0-я знаю его старый, но я учусь использовать его), используя интерфейс IDispatch, и пытаюсь использовать его на C#.

Мой код C# выглядит следующим образом:

static void Main(string[] args)
    {
        Type type = Type.GetTypeFromProgID("Bens.General.1");
            
        Object obj = Activator.CreateInstance(type);

        ITest tObj = (ITest)obj;
            
        Console.WriteLine("Value1: " + tObj.MyValue());

        Console.ReadLine();
    }


(Я также пробовал это с помощью dynamic, но и там не повезло).

со следующим интерфейсом ITest:

[Guid("4B8C6960-EB25-11e7-A3BD-001CF0FAD303")] // This matches my IID in Component QueryInterface

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ITest
    {
        [DispId(1)]
        string MyValue();

        [DispId(2)]
        string Value2();
    }


C++ QueryInterface-это:

HRESULT __stdcall Cmpnt::QueryInterface(const IID& iid, void** ppv)
{
	char buffer[37];

	char* guid = guid_to_str(&iid, buffer);

	MessageBox(NULL, guid, guid, 0);

	if(iid == IID_IUnknown)
	{
		*ppv = static_cast<general*>(this);
	}
	else if(iid == IID_IDispatch)
	{
		*ppv = static_cast<general*>(this);
	}
	else if(iid == IID_general)
	{
		*ppv = static_cast<general*>(this);
	}
	else
	{
		*ppv = NULL;
		return E_NOINTERFACE;
	}
	
	reinterpret_cast<IUnknown*>(*ppv)->AddRef();

	return S_OK;
}


IID_general определенно соответствует GUID в атрибуте ITest.

Что я уже пробовал:

Он отлично работает в VB6 и VBA (Office 2016), но в C# говорит, что интерфейс
{
4B8C6960-EB25-11e7-A3BD-001CF0FAD303
}
Он не реализован, но я точно знаю, что в методе Queryinterface C++ он есть (он работает в VB/VBA, так почему бы и нет C#?)

MessageBox в коде C++ показывает, что C# пытается по крайней мере 10 IID, включая IID_general, который кажется мне странным, но безуспешно. VBA, Excel показывает, что он пробует 6 IID и после этого преуспевает.

Обновление: я обновил свой COM-компонент для поддержки раннего связывания с библиотекой типов, MIDL-генерируемыми интерфейсами и т. д... - опять же, это работает для VBA (Excel), но не в C#.

F-ES Sitecore

Он работает в VB и VBA, поскольку они основаны на COM-языках, поэтому были написаны с нуля для поддержки IDispatch (т. е. они поддерживают как раннее, так и позднее связывание). С c# вся парадигма фреймворка изменилась, чтобы быть строго типизированной, поэтому нет встроенной поддержки таких вещей, как IDispatch. Я считаю, что вы все еще можете получить доступ к методам с помощью reflection\Invoke. Я погуглил "call IDispatch c#" и нашел несколько претендентов, ниже приведен один, но есть и другие, на которые вы тоже можете посмотреть

http://www.productiverage.com/idispatch-iwastedtimeonthis-but-ilearntlots

1 Ответов

Рейтинг:
1

KarstenK

Использование старого VC 6.0-не очень хорошая идея, потому что ему уже почти 20 лет, и поэтому он не соответствует современным разработкам. Вам лучше использовать актуальную версию Visual Studio, потому что старые (VC 6) и новые интерфейсы .net (C#) не являются совместимый.

Взгляните на это Учебник для начинающих для написания простой COM/ATL DLL чтобы увидеть лучшую поддержку. И больше всего он работает на net-платформе и поэтому полностью отлаживается на разных языках!!!