MS_Marshaling - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
ãã€ã¯ããœããæè¡æžã§ã¯ã
- ãããŒãžïŒ.NETïŒã»ã¢ã³ãããŒãžïŒC/C++ïŒã³ãŒãéã®çžäºéçš
- COM ã䜿çšããã€ã³ã»ããã»ã¹åŒã³åºã
- COM ã䜿çšããå¥ã»ããã»ã¹åŒã³åºã
- DCOM ã䜿çšãããªã¢ãŒãã»ãµãŒãåŒã³åºã
ã«ããããããŒã¿å€æããæããŠããããšãå€ãã
-
ããŒã·ã£ãªã³ã°ã®ãMarshalãã¯ã
-
äžè¬çã«ã¯
ãéé æè»å Žã
ïŒåå²åšããã³ããªã©ãçµãŠç®çã®ä»åç·ã«éãèšåãã€ãŒããšãåŒã°ããïŒ
ãæå³ãããã -
IT çšèªãšããŠã¯ã
COM ãªã©ã§å®è£ ãããŠãããããŒã·ã£ãªã³ã°ããæãã
ã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³ãããã»ã¹ãéçºæè¡ãªã©ã®
åå¢çãè¶ããŠããªããžã§ã¯ãã転éããæè¡ã®ç·ç§°
ã§ããã
-
-
éçºæè¡ã®å¢çãè¶ããããã®æè¡ãšããŠã¯ã以äžã®ãã®ãããã
-
ããã»ã¹éã»ãã·ã³éããŒã·ã£ãªã³ã°
COMãDCOMãCOM+ ã§ããã»ã¹éã»ãã·ã³éãè¶ ããŠ
忣ãªããžã§ã¯ããåŒã³åºãéã«å®è¡ãããã -
ãããŒãžãã³ãŒããšã¢ã³ãããŒãžãã³ãŒãã®ããªããž
- .NET åã Win32 DLL ã§äœ¿çšå¯èœãªããŒã¿åã®åŒæ°ã«å€æ
- ãŸãã¯ããã®éã
-
è£è¶³ïŒèªæºã®èª¬æã¯æ£ç¢ºã ããããäžæ®µã®ç±æ¥ãããïŒ: ãééæè»å Žããšãã
説æã¯èŸæžçã«ã¯æ£ããããèšç®æ©çšèªãšããŠã®ç³»èãè£ã£ãŠããããmarshal ã®å矩ãâ ã»å€ãã©ã³ã¯èª marhskalkïŒéЬã®äžè©±äººïŒ â ãæŽåããã / é åºç«ãŠãŠé 眮ããã â è»éã®ãå 垥ïŒMarshalïŒããåèªæº ã»ééçšèªã® marshalling yardïŒæè»å ŽïŒã¯ ã貚è»ãäžŠã¹æ¿ããå Žæã ãèšç®æ©çšèªãšããŠã®æå³ãâ ã»ãã¡ã¢ãªäžã®ãªããžã§ã¯ããã å¢çãè¶ããŠéã¹ã圢ã«ã䞊ã¹çŽããã â ã·ãªã¢ã©ã€ãºïŒçŽååïŒãšè¿ããã ããŒã·ã£ãªã³ã°ã¯ãåç §ã®æ±ããŸã§å«ããç¹ãéã ã·ãªã¢ã©ã€ãº ⊠å€ããã€ãåã«ãã ããŒã·ã£ãªã³ã° ⊠å€ãåç §ãå«ã㊠ãåããåŽã§æå³ãæã€åœ¢ãã«å€æãã â ïŒïŒ Proxy ãç«ãŠãããã³ãã«ãè€è£œããçïŒ
ãããŒãžã³ãŒãã»ã¢ã³ãããŒãžãã³ãŒãéã®ããŒã¿å€æã®ããšã
C/C++ ãš .NET ã§ã¯åœç¶ã¡ã¢ãªäžã®ããŒã¿ã®è¡šçŸãç°ãªãã
äŸãã°ã.NET ã§ã¯ã
- ãã€ã³ã¿ãçŽæ¥æ±ãããšãã§ããªããã
- ãªããžã§ã¯ã㯠GCïŒã¬ããŒãžã³ã¬ã¯ã¿ïŒãªã©ã§ç®¡çãããŠããã
ãªã®ã§ããããŒãžã³ãŒãã»ã¢ã³ãããŒãžãã³ãŒãéã®ããŒã¿å€æãå¿ èŠã«ãªãã
è£è¶³ïŒããã€ã³ã¿ãçŽæ¥æ±ãããšãã§ããªããã¯å°ãå€ãïŒ: åæã®èª¬æã¯
ãå®å šãªã³ãŒãã§ã¯ããšããåæã§ã®è©±ã§ãããæ£ç¢ºã«ã¯æ±ãããã.NET ã§ãã€ã³ã¿ãæ±ãææ®µãâ ã»ãunsafe + ãã€ã³ã¿ãïŒC# ã® unsafe ã³ã³ããã¹ãïŒ unsafe { byte* p = ...; } â ãããžã§ã¯ãã§ AllowUnsafeBlocks ãå¿ èŠ ã»ãIntPtr / nintã⊠ãã³ãã«ãã¢ãã¬ã¹ã®åãæž¡ã ã»ãSpan<T> / Memory<T>ãâ ïŒ.NET Core 2.1ãïŒ â ãunsafe ãªãã§ãé£ç¶ã¡ã¢ãªãå®å šã«æ±ãã â ã¹ã¿ãã¯ã»é åã»ã¢ã³ãããŒãž ã¡ã¢ãªã åãæœè±¡ã§æ±ãã ã»ãfixedã⊠GC ã®ç§»åãæ¢ããŠã¢ãã¬ã¹ãåºå®ãã â â ããã³çãããé·æéè¡ããšããŒããæçåãã ã»ãGCHandleã⊠ãããŒãž ãªããžã§ã¯ãã ã¢ã³ãããŒãžåŽã«æž¡ãéãååãããªãããã«ãã ãæ¬è³ªçãªé£ãããâ ã»GC ãããªããžã§ã¯ããåãããããšãåé¡ã®æ ¹æº â ã¢ã³ãããŒãžåŽã«ã¢ãã¬ã¹ãæž¡ããåŸã§ GC ãåãããšããã®ã¢ãã¬ã¹ã¯ç¡å¹ã«ãªã â ã ããããã³çãããèŠã ã»æææš©ã®æåš â 誰ã確ä¿ãã誰ãè§£æŸããã®ã â åãéãããšãªãŒã¯ or ããŒãç Žå£
ãããŒãžïŒ.NETïŒããã¢ã³ãããŒãžïŒC/C++ïŒã® DLL ã COM ãåŒã³åºãå Žåã
çžäºéçšããŒã·ã£ã©ãŒã«ãã£ãŠã
ãããŒãžã³ãŒãã»ã¢ã³ãããŒãžãã³ãŒãéã®ããŒã¿ã倿ãããã
è£è¶³ïŒå®éã«èºãåïŒ: ãèªåçã«å€æãããããã®ãš
æç€ºçãªæå®ãèŠããã®ããããããã®ãŸãŸéãïŒBlittable åïŒãâ byte, sbyte, short, ushort, int, uint, long, ulong, float, double, IntPtr â ã¡ã¢ãªè¡šçŸãåäžãªã®ã§ãã³ããŒããäžèŠã â é åã Blittable ãªããã³çãããŠçŽæ¥æž¡ãã ã倿ãå¿ èŠïŒNon-Blittable åïŒãâ bool ⊠.NET 㯠1 byteãWin32 ã® BOOL 㯠4 byte â â [MarshalAs(UnmanagedType.Bool)] char ⊠.NET 㯠UTF-16ãC ã¯ç°å¢äŸå string ⊠衚çŸãå šãéãïŒäžèšïŒ æ§é äœ âŠ ã¬ã€ã¢ãŠããéããã ãæååã®æå®ãâ [DllImport("user32", CharSet = CharSet.Unicode)] CharSet.Ansi ⊠char* ïŒå€æã³ã¹ãããïŒ CharSet.Unicode ⊠wchar_t* ãWindows API ã¯æ¬æ¥ãã¡ããâ CharSet.Auto ⊠OS ã«åãããïŒçŸåšã¯å®è³ª UnicodeïŒ ã»é¢æ°åã® A / W æ¥å°ŸèŸã¯ CharSet ã«å¿ããŠãèªåã§ä»ããããã MessageBox â MessageBoxWïŒUnicode æå®æïŒ ã»æ»ãå€ãæååã®å Žå㯠ã誰ãè§£æŸãããããåé¡ã«ãªã â StringBuilder ã§åãã / IntPtr ã§åã㊠Marshal.PtrToStringUni + é©åãªè§£æŸ
Marshal ã¯ã©ã¹ã䜿çšããŠæ§é äœã®ããŒã·ã£ãªã³ã°ãå¯èœã
æ§é äœé åãæ§é äœé åé åãæ§é äœé åã®éå±€æ§é ãªã©ã
-
Marshal ã¯ã©ã¹
https://learn.microsoft.com/ja-jp/dotnet/api/system.runtime.interopservices.marshal -
CustomMarshaler ã¯ã©ã¹
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Frameworks/Infrastructure/Public/Util/CustomMarshaler.cs
æ§é äœé
åã®ããŒã·ã£ãªã³ã°ãè¡ãå Žåã¯ã
èŠçŽ æ°ãªã©ã¯å¥éåŒæ°ãªã©ãçšæããŠææ¡ã§ããããã«ããŠããå¿
èŠãããã
è£è¶³ïŒæ§é äœããŒã·ã£ãªã³ã°ã®å¿ é ç¥èïŒ: ãèŠçŽ æ°ãå¥éæž¡ãããšãã
ææã¯æ¬è³ªçã§ãããC ã®äžçã«ã¯é åé·ã®æŠå¿µããªãããã§ããããStructLayout ã¯å¿ ãæå®ãããâ [StructLayout(LayoutKind.Sequential)] struct POINT { public int x; public int y; } LayoutKind.Sequential ⊠宣èšé ã«äžŠã¹ããæ¢å®ã«ãã¹ããâ LayoutKind.Explicit ⊠FieldOffset ã§äœçœ®ãæç€º ïŒå ±çšäœ union ã®åçŸã«äœ¿ãïŒ LayoutKind.Auto ⊠CLR ãèªç±ã«äžŠã¹æ¿ãã â ãçžäºéçšã«äœ¿ã£ãŠã¯ãããªãã ãPackïŒã¢ã©ã€ã¡ã³ãïŒãâ [StructLayout(LayoutKind.Sequential, Pack = 1)] â C åŽã #pragma pack(1) ãªãåãããå¿ èŠããã â ãåã£ãŠããªããšãã£ãŒã«ãããããã ïŒãšã©ãŒã«ãªãããå€ã ãçãã®ã§çºèŠãé ããïŒâ ãé åãå«ãæ§é äœã [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public int[] values; // åºå®é·é åïŒæ§é äœã«åã蟌ãïŒ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string path; // åºå®é·æååãããã¡ ããµã€ãºã®ç¢ºèªãâ Marshal.SizeOf<T>() ã§ C åŽã® sizeof ãšäžèŽããã ãå¿ ãæ€èšŒããã â äžèŽããªããã°ã¬ã€ã¢ãŠãæå®ã誀ã£ãŠãããæ§é äœé åã®åãæž¡ãïŒåæã®äž»é¡ïŒãâ // ç¢ºä¿ â ã³ã㌠â è§£æŸ ãèªåã§è¡ã int size = Marshal.SizeOf<POINT>(); IntPtr buf = Marshal.AllocHGlobal(size * count); try { for (int i = 0; i < count; i++) Marshal.StructureToPtr(items[i], buf + i * size, false); NativeCall(buf, count); // â ãcount ãå¥éæž¡ããâ } finally { Marshal.FreeHGlobal(buf); // â ãå¿ ãè§£æŸãâ } â» AllocHGlobal / FreeHGlobal ã¯å¯Ÿã§äœ¿ã â» AllocCoTaskMem / FreeCoTaskMem 㯠COM çš â ã確ä¿å ãšè§£æŸå ãåãéãããšããŒããå£ãããâãä»ãªãããœãŒã¹çæãã䜿ãããâ .NET 7 以éã®ãLibraryImportã屿§ [LibraryImport("user32.dll", StringMarshalling = StringMarshalling.Utf16)] internal static partial int MessageBoxW(...); â ã³ã³ãã€ã«æã«ããŒã·ã£ãªã³ã° ã³ãŒããçæããã â ãå®è¡æã®ãªãã¬ã¯ã·ã§ã³ãäžèŠãïŒéã â AOTïŒNative AOTïŒãšçžæ§ããã â â DllImport ã¯ä»ãåãããæ°èŠã¯ LibraryImport æšå¥š
- Microsoft Learn > .NET API ãã©ãŠã¶ãŒ > MarshalByRefObject ã¯ã©ã¹
https://learn.microsoft.com/ja-jp/dotnet/api/system.marshalbyrefobject
è£è¶³ïŒ
MarshalByRefObjectã¯äºå®äžåœ¹ç®ãçµããïŒ: ãã®ã¯ã©ã¹ã¯
.NET Remoting ãšã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³ãåæã«ããŠãããã倿ž¡ãïŒMBVïŒãšåç §æž¡ãïŒMBRïŒãâ ã»[Serializable] ãªã¯ã©ã¹ â ãã³ããŒãçžæåŽã«äœããããïŒMarshal By ValueïŒ ã»MarshalByRefObject ã®æŽŸç â çžæåŽã«ã¯ãProxy ãäœããããïŒMarshal By ReferenceïŒ â ã¡ãœããåŒã³åºããå ã®ãã¡ã€ã³ãžè»¢éããã â ãçŸæ³ã ã»ã.NET Remoting 㯠.NET Core ã«ç§»æ€ãããªãã£ããâ ã»ãAppDomain ã®è€æ°çæãäžå¯èœã ïŒâ [.NET4ã«ããããµã³ãããã¯ã¹åAPI](MS_DotNet4Sandbox) åç §ïŒ ã»MarshalByRefObject åèªäœã¯æ®ã£ãŠãããã ãå®è³ªçã«æå³ãæããªãã ã代æ¿ã ã»ããã»ã¹é â ãgRPC / ååä»ããã€ã / HTTPãâ ã».NET å ã®åé¢ â AssemblyLoadContext ã»ãåããåŽã®ãªããžã§ã¯ããæäœãããæèŠãèŠããªã â gRPC ã®ã¹ããªãŒãã³ã° or SignalR
COMã䜿çšããã€ã³ã»ããã»ã¹åŒã³åºã
çææžã¿ã® STA ã® COM ã³ã³ããŒãã³ãã®ãã€ã³ã¿ã䜿çšããŠ
ãã«ãã¹ã¬ããã»ã¯ã©ã€ã¢ã³ãããåŒã³åºããå Žåã
Windows ã¡ãã»ãŒãžãã¥ãŒã«ãã£ãŠåŒã³åºããçŽååãããã
ãããããŒã·ã£ãªã³ã°ã®äžçš®ã§ããã
ç§»è¡ã¡ã¢ïŒèª€åïŒ: ç§»è¡å ã®ãWindwos ã¡ãã»ãŒãžãã¥ãŒãã
ãWindows ã¡ãã»ãŒãžãã¥ãŒãã«ä¿®æ£ããã
ãªãããã®ä»çµã¿ã®è©³çŽ°ã¯ ãŠã£ã³ã㊠ã¡ãã»ãŒãž ãåç §ã
COMã䜿çšããå¥ã»ããã»ã¹åŒã³åºã
ããŒã«ã«ã»ããã»ã¹ã®åŒæ°ã»æ»ãå€ã®ããŒã¿ããªã¢ãŒãã»ããã»ã¹ã«ã³ããŒããã
ããŒã«ã«ã»ããã»ã¹ã®åŒæ°ã»æ»ãå€ã®ããŒã¿ããªã¢ãŒãã»ãµãŒãã®ããã»ã¹ã«ã³ããŒããã
è£è¶³ïŒDCOM ã®çŸåšïŒ: èšè¿°ã¯æ£ããããéçšäžã®æ³šæã倧ããå€ãã£ãã
ãDCOM 匷åïŒWindows ã®æ¢å®å€æŽïŒãâ CVE-2021-26414 ãžã®å¯Ÿå¿ãšããŠã Microsoft 㯠DCOM ã®ãèªèšŒã¬ãã«ãåŒãäžãããã 2021幎6æ ä¿®æ£æäŸïŒæ¢å®ã¯ç¡å¹ïŒ 2022幎6æ æ¢å®ã§æå¹ïŒç¡å¹åå¯èœïŒ 2023幎3æ ã匷å¶çã«æå¹ãç¡å¹åäžå¯ãâ â å€ã DCOM ã¯ã©ã€ã¢ã³ãïŒãµãŒã㯠ãRPC_E_ACCESS_DENIED çã§åããªããªã£ãã â åæ¹ãæŽæ°ããããDCOM ã®å©çšããããå¿ èŠããã ããããã DCOM ã¯çŸä»£ã®ç°å¢ãšçžæ§ãæªãã ã»ãåçããŒããã䜿ãïŒ135 + é«äœããŒãïŒ â ãã¡ã€ã¢ãŠã©ãŒã« / NAT ãè¶ããããªã ã»èªèšŒã Windows çµ±ååæ ã»é害æã®åãåããæ¥µããŠé£ãã â æ°èŠã§ããã·ã³ãè¶ããŠãªããžã§ã¯ããåŒã¶ããªã ãHTTP / gRPCããéžã¶ â
COM ã®ã«ã¹ã¿ã ããŒã·ã£ãªã³ã°ã説æã«ããã«ã¯ã
ADODB.Recordset ã®ããŒã·ã£ãªã³ã°ãªã©ãè¯ããµã³ãã«ã«ãªãã
-
ADODB.Recordset ã®ãã€ã³ã¿ãæž¡ããšããã»ã¹éãè¶ ããŠã
ADODB.Recordset ã®ãªããžã§ã¯ãéå±€ãã³ããŒãããã -
ããã»ã¹ Aãããã»ã¹ B ã§ ADODB.Recordset ã®ãã€ã³ã¿ãå ±æãããŠããå Žåã
ããã»ã¹ A ã§ ADODB.Recordset ã« AddNew ã¡ãœãããåŒã³åºãè¡ã远å ãããšã
ããã»ã¹éãè¶ ããŠããã»ã¹ B ã® ADODB.Recordset ã«è¡ã远å ãããã
ãŸããã«ã¹ã¿ã ããŒã·ã£ãªã³ã°ãçžäºéçšïŒãããŒãžåã COM ã«å
¬éããïŒã§
䜿çšããããšãå¯èœã
è£è¶³ïŒ
ADODB.RecordsetãäŸã«éžãã ã®ã¯ç確ïŒ: ãã®äŸã
ã«ã¹ã¿ã ããŒã·ã£ãªã³ã°ã®æ¬è³ªããã瀺ããŠããçç±ãè£ã£ãŠããããæ¢å®ã®ããŒã·ã£ãªã³ã°ã§ã¯è¶³ããªãçç±ãâ ã»Recordset ã¯ãè¡ã»åã®éå±€æ§é ããæã€ ã»æ¢å®ã® Proxy/Stub ã§æž¡ããšã 1 ã»ã«èªããã³ã«ãããã»ã¹éåŒã³åºããçºçããã â 1000 è¡ Ã 20 å = 20,000 åŸåŸ© â å®çšã«ãªããªã â ãã«ã¹ã¿ã ããŒã·ã£ãªã³ã°ãããããšã ã»IMarshal ã€ã³ã¿ãŒãã§ãŒã¹ãå®è£ ãã ãèªåãã©ãéã¶ããããèªåã§æ±ºããã ã»Recordset 㯠â ãäžèº«ãäžžããšã·ãªã¢ã©ã€ãºããŠäžåºŠã«éãã â åããåŽã§åŸ©å ããïŒïŒå®è³ª Marshal By ValueïŒâ â ã ããããã€ã³ã¿ãæž¡ããã®ã«ã³ããŒãããã ãšããåæã®èгå¯ã«ãªã ãåæã® 2 çªç®ã®èšè¿°ã«ã€ããŠã ãããã»ã¹ A ã§ AddNew ãããš ããã»ã¹ B ã«ãè¡ã远å ãããã â ããã¯ãåæãããã¬ã³ãŒãã»ããã§ã¯ãªãã æ¥ç¶ããããŸãŸ Proxy ãçµç±ããŠããå Žåãã®æå â ADODB.Recordset 㯠ãåæïŒDisconnectedïŒããšãæ¥ç¶ãã§ ããŒã·ã£ãªã³ã°ã®æ¯ãèããå€ãã â â äž¡æ¹ã®èšè¿°ã䜵èšãããŠããã®ã¯ ãã® 2 ã¢ãŒããåæ ããŠãããçŸä»£ã«ãããåãåé¡ãâ ãç²åºŠã®çްããåŒã³åºããå¢çè¶ãã«ãããªã ãšããæèšã¯ãä»ããã®ãŸãŸéçšããã ã»N+1 ã¯ãšãªåé¡ïŒORMïŒ ã»REST API ã® chatty ãªèšèš â ããŸãšã㊠1 åã§éã¶ãïŒDTO / ãããååŸïŒ â GraphQL / gRPC ã®ã¹ããªãŒãã³ã°ã ãã®èª²é¡ãžã®åçã§ãã
-
ããŒã·ã£ãªã³ã°ãmarshallingãã®æå³ - åœèªèŸæž - gooèŸæž
http://dictionary.goo.ne.jp/leaf/jn2/206616/m0u/ -
ITçšèªèŸå žãã€ããª
- ãããŒãžã³ãŒããšã¯ ããããŒãžãã³ãŒãã (managed code)
http://www.sophia-it.com/content/%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%82%B3%E3%83%BC%E3%83%89 - ã¢ã³ãããŒãžãã³ãŒããšã¯ ãã¢ã³ãããŒãžã³ãŒãã (unmanaged code)
http://www.sophia-it.com/content/%E3%82%A2%E3%83%B3%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%82%B3%E3%83%BC%E3%83%89
- ãããŒãžã³ãŒããšã¯ ããããŒãžãã³ãŒãã (managed code)
ç§»è¡ã¡ã¢ïŒèªå·±ãªã³ã¯ïŒ: ç§»è¡å ã§ã¯åèã® 1 ä»¶ç®ã
[[ããŒã·ã£ãªã³ã°]]ãmarshallingãã®æå³ãš
èªããŒãžãžã®ãªã³ã¯ãå«ã圢ã«ãªã£ãŠããããããªã³ã¯ãå€ããã
Tags: ç§»è¡, Windows, ããã°ã©ãã³ã°, .NETéçº