COM에서 호출 코드로의 콜백을 허용하는 COM 인터페이스를 만들려고합니다. C#에서 이에 대한 적절한 설명을 찾을 수없는 것 같습니다.COM 콜백을 구현하고 등록하는 방법
정상적인 COM 인터페이스가 작동하지만 콜백 파트를 올바르게 등록하고 설정하는 방법을 모르겠습니다.
"com"은 .com 사이트로 연결되며 실제 com 인터페이스는 포함하지 않는 대부분의 Google 검색어로 C#에서이를 올바르게 수행하는 방법에 대한 정보를 찾을 수 없습니다. 콜백 및 이벤트에 대해 이야기 할 때, 그들은 기본 non-com 것들만 포함합니다. 더 나은 정보를 얻을 수있는 출처를 지적한 경우에도 도움이 될 것입니다.
내 콜백 인터페이스는 다음과 같습니다
using System;
using System.Runtime.InteropServices;
namespace ComAdapter
{
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("7f176b75-7b66-463a-94ab-493943792f88")]
public interface INet40Callback
{
[PreserveSig]
void Callback(string data);
}
}
I는 다음과 같이 노력 콜백 클래스 :
호출 응용 프로그램은 지금까지 다음과 같습니다using net40lib;
using System;
using System.Runtime.InteropServices;
namespace ComAdapter
{
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(INet40Callback))]
[Guid("023e4ad9-77d1-461e-af89-4cfc2b53959c")]
public class Net40Callback : INet40CallbackRegistration
{
[ComVisible(false)]
public delegate void MyCallbackDelegate(string data);
public event MyCallbackDelegate Callback;
public INet40Callback callbackObject;
public Net40Callback()
{
Net40Class.Instance.VersionSent += Instance_VersionSent;
}
void Instance_VersionSent(object sender, EventArgs e)
{
if (callbackObject != null)
{
callbackObject.Callback("blah");
}
if (Callback != null)
{
Console.WriteLine("Instance_VersionSent Sending Callback");
Callback("blah");
}
}
public void RegisterCallback(INet40Callback reg)
{
if (reg is INet40Callback)
{
callbackObject = reg as INet40Callback;
}
}
}
}
:
using ComAdapter;
using System;
using System.Runtime.InteropServices;
namespace net20lib
{
class Net40Callback : INet40Callback
{
[PreserveSig]
public void Callback(string data)
{
Console.WriteLine("Callback Called with data {0}", data);
}
}
}
등록 :
using System;
using System.Runtime.InteropServices;
namespace ComAdapter
{
[ComVisible(true)]
[Guid("3b2ab267-9e9a-47be-ab0a-f55db10a971e")]
public interface INet40CallbackRegistration
{
void RegisterCallback(INet40Callback callback);
}
}
테스트 클래스에서 호출 : 다음은 인터페이스의 구현 : C에서 #
INet40Callback callback = new Net40Callback();
Type myCallbackType = Type.GetTypeFromProgID("ComAdapter.Net40Callback");
object myCallbackInstance = Activator.CreateInstance(myCallbackType);
INet40CallbackRegistration registration = (INet40CallbackRegistration)myCallbackInstance;
registration.RegisterCallback(callback);
정확히 작동하지 않는 것은 무엇입니까? 귀하의 클라이언트 COM 테스트 애플 리케이션은'RegisterCallback'을 전혀 호출합니까? 목록에있는 C# 코드에는이 코드가 표시되지 않습니다. COMSourceInterfaces는 Interop Runtime이 암시 적으로 구현하는 IConnectionPointContainer 인터페이스를 통해 COM에 C# 클래스 이벤트를 노출하고자 할 때 사용됩니다. – Noseratio
감사. 정보를 업데이트하고 지금 당장 시도한 코드를 업데이트했습니다. 내 코드가 현재 어떻게 보이는지 나타낼 수 있습니다 (작동에 더 가까워 야하지만 여전히 그렇지는 않습니다.) 콜백 클래스를 만들고 인터페이스로 등록하십시오.내 문제가 바로 지금 것 같다는 인터페이스가 올바르지 않다는 것을 알려주는, "HRESULT : 0x80004002 (E_NOINTERFACE)"InvalidCastException 얻을. 예외 텍스트는 독일어로되어 있으므로별로 도움이되지 않습니다. –
영어로 예외를 찾아 보았습니다. 'System .__ ComObject'유형의 COM 개체를 인터페이스 유형 'ComAdapter.INet40Callback'으로 캐스팅 할 수 없습니다. 다음 오류로 인해 IID '{XXXXXXXX-XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'인터페이스의 COM 구성 요소에서 QueryInterface 호출이 실패했기 때문에이 작업이 실패했습니다. 해당 인터페이스가 지원되지 않습니다 (HRESULT 예외 : 0x80004002 (E_NOINTERFACE)). . –