.NET의 열거 형은 AutoDispatch
값이고 AutoDual
값이지만 AutoUnknown
값은 없습니다. 왜 그렇게하지 않았고 누구나 이미 자동화 된 방법으로이를 완성 했으므로 바퀴를 다시 만들 필요가 없습니다. 여기에 좀 더 배경에 대한System.Runtime.InteropServices.ClassInterfaceType 열거 형에 AutoUnknown 값이없는 이유는 무엇입니까?
현재 열거에 세 개의 값이며, 그들이 무엇 :
ClassInterfaceType.None
당신을위한 클래스 인터페이스를 만들지 않습니다. 이것은 Microsoft의 권장 값입니다. 클래스 인터페이스가 없으므로 의도하는 멤버와 함께 자신 만의 인터페이스를 만들어 클래스에 구현해야합니다. 그런 다음 인터페이스에 System.Runtime.InteropServices.ClassInterfaceAttribute 속성을 사용하여 인터페이스에 인터페이스 (런타임에 바인딩 된 클라이언트 지원), 알 수없는 인터페이스 (초기 바인딩 클라이언트 지원) 또는 이중 (초기 및 후기 바인딩 클라이언트 모두 지원)로 만들 수 있습니다.ClassInterfaceType.AutoDispatch
은 명시 적 구성원이없는IDispatch
에서 파생 된 클래스 인터페이스를 만듭니다. 명시 적 구성원이 없기 때문에 후기 바인딩 호출자 만 지원할 수 있습니다.ClassInterfaceType.AutoDual
은IDispatch
에서 파생 된 클래스 인터페이스를 만들고 은에 해당 클래스의 public 비 정적 멤버 및 모든 구현 된 인터페이스의 명시적인 멤버를 명시합니다. Microsoft는 클래스의 멤버 중 하나라도 변경되면 클래스 인터페이스도 변경된다는 사실로 인해 "버전 제한으로 인해"이 값을 사용하지 않을 것을 강력하게 권장합니다. (재 바인드를하지 않는 클래스 후 발신자가 잘못된 메서드를 호출하거나 잘못된 매개 변수를 전달 끝낼 수 있었다 변경되었습니다 그래서.) 그래서
ClassInterfaceType.AutoUnknown
라는 값이없는 이유입니다 궁금하네요 무엇 이 클래스는 명시 적으로 클래스의 멤버를 선언하는 IUnknown
에서 파생 된 클래스 인터페이스를 만듭니다 (기본 클래스 또는 구현하는 다른 인터페이스는 제외).
기본 클래스의 모든 멤버와 모든 구현 된 인터페이스를 노출하는 대신 클래스의 직접 멤버 만 노출한다는 점을 제외하고는 AutoDual과 비슷한 ClassInterfaceType.AutoDualDirect
과 같을 것으로 예상됩니다. 다른 COM 인터페이스를 통해 다른 멤버를 검색 할 수 있기 때문입니다.
여기에 무슨 이야기가 있습니다. 무엇이 빠졌습니까? 마이크로 소프트가 "버전 관리 문제"때문에 AutoDual을 사용하지 말 것을 권장하며, 이러한 우려는 AutoUnknown에도 어느 정도 적용될 것이라고 말했습니다. 하지만 그 권고에도 불구하고 그들은 여전히 AutoDual 있습니다. 왜 그들은 또한 AutoUnknown을 가지고 있지 않을까요?
"버전 관리 문제"에 대한 단어 : 이러한 우려의 가장 위험한 측면은 늦게 바인딩 된 발신자에만 적용됩니다. AutoUnknown은 IDispatch
- 유도 된 인터페이스가 아닌 IUnknown
- 유도 된 인터페이스를 생성하므로 사전 바인딩 된 클라이언트가 가질 수있는 버전 문제에 신경을 써야합니다. 그리고 자동 생성 클래스 인터페이스의 IID는 클래스의 public 비 정적 멤버가 변경 될 때마다 변경되므로 초기 바인딩 클라이언트는 기존 멤버에 "불량 호출"을 할 수 없으며 단순히 QueryInterface에 실패합니다 () 클래스 인터페이스. 여전히 실패이지만, 관리할만한 것이지 충돌이나 다른 것이 아닙니다. 이것은 인터페이스를 변경하지 못하게하는 COM 규칙을 깨지 않습니다. 변화하지 않고 새로운 인터페이스 (새로운 IID)가되었습니다. 실제로 AutoDual 메커니즘의 절반 인 (파생 된 멤버를 뺀) IUnknown
과 실질적으로 다르지 않습니다.실제로, 은보다 적습니다. AutoDual에는 모든 지연된 문제점이 있기 때문에 AutoDual보다 "버전 문제"가 있습니다.
다시 질문 드리겠습니다 : AutoUnknown이없는 경우 왜 AutoDual이 존재합니까?
using System.Runtime.InteropServices;
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class F
{
public int foo()
{
return 5;
}
}
다음 IDL 생성 :
고려, 다음 C# 코드 몇 가지 실제 예제를 부여하려면[
uuid(1F3A7DE1-99A1-37D4-943E-1BF5CFDF7DFA),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "F")
]
coclass F {
[default] interface _F;
interface _Object;
};
[
odl,
uuid(3D0A1144-1C0B-3877-BE45-AD8318898790),
hidden,
dual,
nonextensible,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "F")
]
interface _F : IDispatch {
[id(00000000), propget,
custom(54FC8F55-38DE-4703-9C4E-250351302B1C, 1)]
HRESULT ToString([out, retval] BSTR* pRetVal);
[id(0x60020001)]
HRESULT Equals(
[in] VARIANT obj,
[out, retval] VARIANT_BOOL* pRetVal);
[id(0x60020002)]
HRESULT GetHashCode([out, retval] long* pRetVal);
[id(0x60020003)]
HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x60020004)]
HRESULT foo([out, retval] long* pRetVal);
};
괜찮습니다,하지만 난 AutoUnknown가 유용하게이 IDL을 대신 생성하는 것을 제안 할 것 :
[
uuid(1F3A7DE1-99A1-37D4-943E-1BF5CFDF7DFA),
version(1.0),
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "F")
]
coclass F {
[default] interface _F;
interface _Object;
};
[
odl,
uuid(BC84F393-DACC-353F-8DBE-F27CB2FB4757),
version(1.0),
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "_F")
]
interface _F : IUnknown {
HRESULT _stdcall foo([out, retval] long* pRetVal);
};
자동으로 수행 할 방법이 없다면 n 오, 내가 그것을 할 리플렉션을 사용하는 무언가를 쓰게 될 것이므로, 나는 또한 사물의 그 측면에 대한 어떤 권고도 감사 할 것입니다. 예를 들어, 메소드에서 확인해야하는 속성이 있습니까? 매개 변수에? 나는 그것을 어떻게하는지 알기 위해 System.Runtime.InteropServices.TypeLibConverter
의 IL을 파 냈다. 그러나 불행히도 모든 좋은 것들은 내가 얻을 수없는 개인 internalcall nConvertAssemblyToTypeLib() 함수에있다.
감사합니다.
[ClassInterfaceType]의 의미부터 시작하여 COM의 작동 방식을 근본적으로 오해 할 수 있습니다. 그것을 설명하면 책이 필요하며, 많은 책들이 있습니다. –
저는 COM이 어떻게 작동하는지 아주 잘 압니다. 물론 더 많은 것을 배우기 위해서, 많은 책들이 있다는 관찰에 감사드립니다. 어쨌든, 내 질문을 되풀이하다 : 나는 클래스의 공개 비 정적 멤버를 기반으로'IUnknown' 파생 인터페이스를 전적으로 필요로 할 것이므로 커뮤니티에서 자동 생성을위한 아이디어를 얻고 각각의 변화가 일어날 때마다 그것들을 써야합니다. 인터페이스를 직접 작성하지 않고 후기 바인딩 클라이언트를 허용하지 않는 대체 방법을 포함하여 모든 건설적인 아이디어에 대해 개방적입니다. 고맙습니다. – bob
"필자는'AutoDual'이 제공하는 것과 정확히 똑같은 클래스의 public non-static 멤버를 기반으로하는'IUnknown' 파생 인터페이스를 필요로 할 것입니다. –