No_Name_3
@No_Name_3 (No Name)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

IDCompositionDevice3のメソッドで返ってくるものは一体何なのでしょうか?

解決したいこと

IDCompositionDevice3が作成できるIDCompositionGaussianBlurEffectやIDCompositionBrightnessEffectなどののメソッドが実行できるようになれば解決です。

発生している問題・エラー

C#でdcomp.hのIDCompositionDevice3インターフェイスのメソッド動作が思い通りになりません。
CreateGaussianBlurEffectやCreateBrightnessEffectなどIDCompositionDevice3のメソッドで返ってくるポインターがCOMオブジェクトではないようなエラーになります。
返されてくるポインターが何者なのか全く分かりません。

出ているエラーメッセージを入力
System.InvalidCastException: インターフェイスがサポートされていません (HRESULT からの例外:0x80004002 (E_NOINTERFACE))

該当するソースコード

		public Form1()
		{
			D3D11CreateDevice(IntPtr.Zero, 1/*D3D_DRIVER_TYPE_HARDWARE*/, IntPtr.Zero, 32/*D3D11_CREATE_DEVICE_BGRA_SUPPORT*/, null, 0, 7, out IntPtr ppDevice, out IntPtr _, out IntPtr _);
	
			Guid dxgiDevice4Guid = Marshal.GenerateGuidForType(typeof(IDXGIDevice4));
			Marshal.QueryInterface(ppDevice, ref dxgiDevice4Guid, out IntPtr dxgiDevice);
			Guid d2d1Factory7Guid = Marshal.GenerateGuidForType(typeof(ID2D1Factory7));

			D2D1CreateFactory(0/*D2D1_FACTORY_TYPE_SINGLE_THREADED*/, d2d1Factory7Guid, 0/*D2D1_DEBUG_LEVEL_NONE*/, out ID2D1Factory7 pplFactory);

			pplFactory.CreateDevice(dxgiDevice, out IntPtr ppD2D1Device6);

			DCompositionCreateDevice3(ppD2D1Device6, Marshal.GenerateGuidForType(typeof(IDCompositionDesktopDevice)), out IntPtr dcompositionDevice);
			IDCompositionDevice3 dCompositionDevice3 = (IDCompositionDevice3)Marshal.GetObjectForIUnknown(dcompositionDevice);
			//System.InvalidCastException: インターフェイスがサポートされていません (HRESULT からの例外:0x80004002 (E_NOINTERFACE))
			//m_DCompositionDevice3.CreateGaussianBlurEffect(out IDCompositionGaussianBlurEffect dCompositionGaussianBlurEffect);
			dCompositionDevice3.CreateGaussianBlurEffect(out IntPtr ppGaussianBlurEffect);
			dCompositionDevice3.CreateBrightnessEffect(out IntPtr ppBrightnessEffect);
			dCompositionDevice3.CreateColorMatrixEffect(out IntPtr ppColorMatrixEffect);
			try
			{
				Marshal.GetObjectForIUnknown(ppGaussianBlurEffect);
			}
			catch (InvalidCastException ex)
			{
				//System.InvalidCastException: インターフェイスがサポートされていません (HRESULT からの例外:0x80004002 (E_NOINTERFACE))
			}
			try
			{
				Marshal.GetObjectForIUnknown(ppBrightnessEffect);
			}
			catch (InvalidCastException ex)
			{
				//System.InvalidCastException: インターフェイスがサポートされていません (HRESULT からの例外:0x80004002 (E_NOINTERFACE))
			}
			try
			{
				Marshal.GetObjectForIUnknown(ppColorMatrixEffect);
			}
			catch (InvalidCastException ex)
			{
				//System.InvalidCastException: インターフェイスがサポートされていません (HRESULT からの例外:0x80004002 (E_NOINTERFACE))
			}

		}
		[DllImport("d2d1")]
		public static extern int D2D1CreateFactory(uint factoryType, in Guid riid, in uint pFactoryOptions, out ID2D1Factory7 ppIFactory);
		[DllImport("d3d11")]
		public static extern int D3D11CreateDevice(IntPtr pAdapter, uint DriverType, IntPtr Software, uint Flags, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] uint[] pFeatureLevels, uint FeatureLevels, uint SDKVersion, out IntPtr ppDevice, out IntPtr pFeatureLevel, out IntPtr ppImmediateContext);
		[DllImport("dcomp")]
		public static extern int DCompositionCreateDevice3(IntPtr renderingDevice, in Guid iid, out IntPtr dcompositionDevice);

		[ComImport]
		[Guid("0987CB06-F916-48BF-8D35-CE7641781BD9")]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		public interface IDCompositionDevice3
		{
			int Commit();
			int WaitForCommitCompletion();
			int GetFrameStatistics();
			int CreateVisual();
			int CreateSurfaceFactory();
			int CreateSurface();
			int CreateVirtualSurface();
			int CreateTranslateTransform();
			int CreateScaleTransform();
			int CreateRotateTransform();
			int CreateSkewTransform();
			int CreateMatrixTransform();
			int CreateTransformGroup();
			int CreateTranslateTransform3D();
			int CreateScaleTransform3D();
			int CreateRotateTransform3D();
			int CreateMatrixTransform3D();
			int CreateTransform3DGroup();
			int CreateEffectGroup();
			int CreateRectangleClip();
			int CreateAnimation();
			[PreserveSig]
			int CreateGaussianBlurEffect(out IntPtr/*IDCompositionGaussianBlurEffect*/ gaussianBlurEffect);
			[PreserveSig]
			int CreateBrightnessEffect(out IntPtr/*IDCompositionBrightnessEffect*/ brightnessEffect);
			[PreserveSig]
			int CreateColorMatrixEffect(out IntPtr/*IDCompositionColorMatrixEffect*/ colorMatrixEffect);
			[PreserveSig]
			int CreateShadowEffect(out IntPtr/*IDCompositionShadowEffect*/ shadowEffect);
			[PreserveSig]
			int CreateHueRotationEffect(out IntPtr/*IDCompositionHueRotationEffect*/ hueRotationEffect);
			[PreserveSig]
			int CreateSaturationEffect(out IntPtr/*IDCompositionSaturationEffect*/ saturationEffect);
			[PreserveSig]
			int CreateTurbulenceEffect(out IntPtr/*IDCompositionTurbulenceEffect*/ turbulenceEffect);
			[PreserveSig]
			int CreateLinearTransferEffect(out IntPtr/*IDCompositionLinearTransferEffect*/ linearTransferEffect);
			[PreserveSig]
			int CreateTableTransferEffect(out IntPtr/*IDCompositionTableTransferEffect*/ tableTransferEffect);
			[PreserveSig]
			int CreateCompositeEffect(out IntPtr/*IDCompositionCompositeEffect*/ compositeEffect);
			[PreserveSig]
			int CreateBlendEffect(out IntPtr/*IDCompositionBlendEffect*/ blendEffect);
			[PreserveSig]
			int CreateArithmeticCompositeEffect(out IntPtr/*IDCompositionArithmeticCompositeEffect*/ arithmeticCompositeEffect);
			[PreserveSig]
			int CreateAffineTransform2DEffect(out IntPtr/*IDCompositionAffineTransform2DEffect*/ affineTransform2dEffect);
		}
		[ComImport]
		[Guid("95B4F95F-D8DA-4CA4-9EE6-3B76D5968A10")]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		public interface IDXGIDevice4 { }
		[ComImport]
		[Guid("bdc2bdd3-b96c-4de6-bdf7-99d4745454de")]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		public interface ID2D1Factory7
		{
			int ReloadSystemMetrics();
			void GetDesktopDpi();
			int CreateRectangleGeometry();
			int CreateRoundedRectangleGeometry();
			int CreateEllipseGeometry();
			int CreateGeometryGroup();
			int CreateTransformedGeometry();
			int CreatePathGeometry();
			int CreateStrokeStyle();
			int CreateDrawingStateBlock();
			int CreateWicBitmapRenderTarget();
			int CreateHwndRenderTarget();
			int CreateDxgiSurfaceRenderTarget();
			int CreateDCRenderTarget();
			int CreateDevice();
			int CreateStrokeStyle2();
			int CreatePathGeometry2();
			int CreateDrawingStateBlock2();
			int CreateGdiMetafile();
			int RegisterEffectFromStream();
			int RegisterEffectFromString();
			int UnregisterEffect();
			int GetRegisteredEffects();
			int GetEffectProperties();
			int CreateDevice1();
			int CreateDevice2();
			int CreateDevice3();
			int CreateDevice4();
			int CreateDevice5();
			[PreserveSig]
			int CreateDevice(IntPtr dxgiDevice, out IntPtr d2dDevice6);
		}
		[ComImport]
		[Guid("45D4D0B7-1BD4-454E-8894-2BFA68443033")]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		public interface IDCompositionGaussianBlurEffect { }


dcomp.h IDCompositionDevice3の定義
image.png

自分で試したこと

CreateGaussianBlurEffectメソッドで返るポインターが何を示しているのかが不明ですが、32バイトのオフセットと36バイトのオフセットで読んだときに返る値はCOMオブジェクトでした。32バイトオフセットの方はIDCompositionDevice3を実装していることも確認しました。

			IntPtr ptrPlus32 = Marshal.ReadIntPtr(ppGaussianBlurEffect, 32);
			IntPtr ptrPlus36 = Marshal.ReadIntPtr(ppGaussianBlurEffect, 36);
			IDCompositionDevice3 device3 = Marshal.GetObjectForIUnknown(ptrPlus32)as IDCompositionDevice3;
0

1Answer

Microsoft 公式の winapi pinvoke 集である Microsoft.Windows.CsWin32 を導入して 自前の interface の定義をやめればいいのではないでしょうか?

例えば次の様な感じに定義します。

csproj
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
+    <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.49-beta">
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
  </ItemGroup>
</Project>
NativeMethods.txt
IDCompositionDevice3

下記での操作は visual studio での操作です vscode の場合は適宜対応するショートカットを読み替えてください。

あとは IDCompositionDevice3 と書いて Ctrl + . で型の確認すれば下記の様に定義された型が確認できます。
image.png

参照がつながる状態にすれば F12 で定義に飛べます。
image.png

そうすれば型をわざわざ定義されなくても、実態としての型にアクセスして利用できるのではないでしょうか?

image.png

image.png

0Like

Comments

  1. @No_Name_3

    Questioner

    @junerさん回答ありがとうございます。

    CsWin32で試してみたこともありますが、駄目でした。
    また、NuGetで取得できるDirectXの内容を定義したライブラリを使用しても同様に実行できませんでした。

    IntPtrで受け取っている箇所をIDCompositionGaussianBlurEffectに書き換えても「インターフェイスがサポートされていません。」の例外になってしまいます。

    最終的にはC++でIDCompositionGaussianBlurEffectのメソッドを実行する関数を作成し、これを呼び出すことで解決しました。

Your answer might help someone💌