Language
Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
çžäºéçšããŒã·ã£ãªã³ã°ã¯ãã¡ãœãã ãã©ã¡ãŒã¿ãŒã«é¢é£ä»ããããŠããããŒã¿ããããŒãžã ã¡ã¢ãªãšã¢ã³ãããŒãžã ã¡ã¢ãªã®éãééããå Žåã®åäœã決å®ããã«ãŒã«ã«å¯ŸããŠåäœããŸãã ãããã®çµã¿èŸŒã¿ã«ãŒã«ã¯ãããŒã¿å倿ãªã©ã®ããŒã·ã£ãªã³ã° ã¢ã¯ãã£ããã£ãåŒã³åºãå ãæž¡ãããããŒã¿ã倿ŽããŠåŒã³åºãå ã«ãããã®å€æŽãè¿ãããšãã§ãããã©ãããããã³ããŒã·ã£ã©ãŒãããã©ãŒãã³ã¹ã®æé©åãæäŸããç¶æ³ãå¶åŸ¡ããŸãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãçžäºéçšããŒã·ã£ãªã³ã° ãµãŒãã¹ã®æ¢å®ã®åäœç¹æ§ãèå¥ããŸãã é åãããŒã«åãchar åãããªã²ãŒããã¯ã©ã¹ããªããžã§ã¯ããæååãæ§é äœã®ããŒã·ã£ãªã³ã°ã«é¢ãã詳现æ å ±ã衚瀺ãããŸãã
Note
ãžã§ããªãã¯åã®ããŒã·ã£ãªã³ã°ã¯ãµããŒããããŠããŸããã 詳现ã«ã€ããŠã¯ãã ãžã§ããªãã¯åã䜿çšããçžäºéçšããåç §ããŠãã ããã
ã€ã³ã¿ãŒãªãã¬ãŒã·ã§ã³ ããŒã·ã£ã©ãŒã䜿çšããã¡ã¢ãªç®¡ç
çžäºéçšããŒã·ã£ã©ãŒã¯åžžã«ãã¢ã³ãããŒãž ã³ãŒãã«ãã£ãŠå²ãåœãŠãããã¡ã¢ãªã®è§£æŸã詊ã¿ãŸãã ãã®åäœã¯ COM ã¡ã¢ãªç®¡çèŠåã«æºæ ããŠããŸããããã€ãã£ã C++ ã管çããèŠåãšã¯ç°ãªããŸãã
ãã©ãããã©ãŒã åŒã³åºãã䜿çšãããšãã«ãã€ãã£ãã® C++ åäœ (ã¡ã¢ãªè§£æŸãªã) ãäºæ³ãããå Žåãæ··ä¹±ãçºçããå¯èœæ§ããããŸãããã©ãããã©ãŒã åŒã³åºãã§ã¯ããã€ã³ã¿ãŒã®ã¡ã¢ãªãèªåçã«è§£æŸãããŸãã ããšãã°ãC++ DLL ããæ¬¡ã®ã¢ã³ãããŒãž ã¡ãœãããåŒã³åºããŠããã¡ã¢ãªã¯èªåçã«è§£æŸãããŸããã
é管ç眲å
BSTR MethodOne (BSTR b) {
return b;
}
ãã ãããã©ãããã©ãŒã åŒã³åºããããã¿ã€ããšããŠã¡ãœãããå®çŸ©ããå BSTR åã String åã«çœ®ãæãã MethodOneãåŒã³åºããšãå
±éèšèªã©ã³ã¿ã€ã 㯠b ã 2 åè§£æŸããããšããŸãã ããŒã·ã£ãªã³ã°åäœã¯ãIntPtråã§ã¯ãªãStringåã䜿çšããŠå€æŽã§ããŸãã
ã©ã³ã¿ã€ã ã§ã¯ãåžžã« Windows ã® CoTaskMemFree ã¡ãœãããšãä»ã®ãã©ãããã©ãŒã ã® free ã¡ãœããã䜿çšããŠã¡ã¢ãªãè§£æŸããŸãã 䜿çšããŠããã¡ã¢ãªã Windows ã® CoTaskMemAlloc ã¡ãœãããŸãã¯ä»ã®ãã©ãããã©ãŒã ã® malloc ã¡ãœããã§å²ãåœãŠãããªãã£ãå Žåã¯ã IntPtr ã䜿çšããé©åãªã¡ãœããã䜿çšããŠã¡ã¢ãªãæåã§è§£æŸããå¿
èŠããããŸãã åæ§ã«ãã«ãŒãã« ã¡ã¢ãªãžã®ãã€ã³ã¿ãŒãè¿ã Kernel32.dllãã GetCommandLine 颿°ã䜿çšããå Žåãªã©ãã¡ã¢ãªãè§£æŸããªãç¶æ³ã§ãã¡ã¢ãªã®èªåè§£æŸãåé¿ã§ããŸãã ã¡ã¢ãªãæåã§è§£æŸããæ¹æ³ã®è©³çްã«ã€ããŠã¯ã ãããã¡ãŒã®ãµã³ãã«ãåç
§ããŠãã ããã
ã¯ã©ã¹ã«å¯Ÿããæ¢å®ã®ããŒã·ã£ãªã³ã°
ã¯ã©ã¹ã¯ COM çžäºéçšã«ãã£ãŠã®ã¿ããŒã·ã£ãªã³ã°ã§ããåžžã«ã€ã³ã¿ãŒãã§ã€ã¹ãšããŠããŒã·ã£ãªã³ã°ãããŸãã å Žåã«ãã£ãŠã¯ãã¯ã©ã¹ã®ããŒã·ã£ãªã³ã°ã«äœ¿çšãããã€ã³ã¿ãŒãã§ã€ã¹ã¯ãã¯ã©ã¹ ã€ã³ã¿ãŒãã§ã€ã¹ãšåŒã°ããŸãã ã¯ã©ã¹ ã€ã³ã¿ãŒãã§ã€ã¹ã奜ã¿ã®ã€ã³ã¿ãŒãã§ã€ã¹ã§ãªãŒããŒã©ã€ãããæ¹æ³ã«ã€ããŠã¯ãã ã¯ã©ã¹ ã€ã³ã¿ãŒãã§ã€ã¹ã®æŠèŠããåç §ããŠãã ããã
COM ã«ã¯ã©ã¹ãæž¡ã
ãããŒãžã ã¯ã©ã¹ã COM ã«æž¡ããããšãçžäºéçšããŒã·ã£ã©ãŒã¯èªåçã« COM ãããã·ã§ã¯ã©ã¹ãã©ãããããããã·ã«ãã£ãŠçæãããã¯ã©ã¹ ã€ã³ã¿ãŒãã§ã€ã¹ã COM ã¡ãœããåŒã³åºãã«æž¡ããŸãã ãããã·ã¯ãã¯ã©ã¹ ã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¹ãŠã®åŒã³åºãããããŒãžã ãªããžã§ã¯ãã«å§ä»»ããŸãã ãããã·ã¯ãã¯ã©ã¹ã«ãã£ãŠæç€ºçã«å®è£
ãããŠããªãä»ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå
¬éããŸãã ãããã·ã¯ãã¯ã©ã¹ã«ä»£ãã£ãŠã IUnknown ã IDispatch ãªã©ã®ã€ã³ã¿ãŒãã§ã€ã¹ãèªåçã«å®è£
ããŸãã
.NET ã³ãŒãã«ã¯ã©ã¹ãæž¡ã
ã³ã¯ã©ã¹ã¯ãéåžžãCOM ã®ã¡ãœããåŒæ°ãšããŠäœ¿çšãããŸããã 代ããã«ãéåžžãæ¢å®ã®ã€ã³ã¿ãŒãã§ã€ã¹ãã³ã¯ã©ã¹ã®ä»£ããã«æž¡ãããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ããããŒãžã ã³ãŒãã«æž¡ããããšãçžäºéçšããŒã·ã£ã©ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãé©åãªã©ãããŒã§ã©ããããã©ãããŒããããŒãžã ã¡ãœããã«æž¡ã圹å²ãæ ããŸãã ã©ã®ã©ãããŒã䜿çšãããã¯é£ãã倿ãšãªãããšããããŸãã COM ãªããžã§ã¯ãã®ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ã«ã¯ããªããžã§ã¯ããå®è£ ããã€ã³ã¿ãŒãã§ã€ã¹ã®æ°ã«é¢ä¿ãªãã1 ã€ã®äžæã®ã©ãããŒããããŸãã ããšãã°ã5 ã€ã®ç°ãªãã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãã 1 ã€ã® COM ãªããžã§ã¯ãã«ã¯ãã©ãããŒã 1 ã€ã ãååšããŸãã åãã©ãããŒã¯ã5 ã€ã®ã€ã³ã¿ãŒãã§ã€ã¹ãã¹ãŠãå ¬éããŸãã COM ãªããžã§ã¯ãã® 2 ã€ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããããšãã©ãããŒã® 2 ã€ã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã
ã©ãããŒãæå¹æéãéããŠåãåãç¶æããã«ã¯ãçžäºéçšããŒã·ã£ã©ãŒã¯ããªããžã§ã¯ãã«ãã£ãŠå ¬éãããã€ã³ã¿ãŒãã§ã€ã¹ãããŒã·ã£ã©ãŒãåããŠééããéã«ãæ£ããã©ãããŒãèå¥ããå¿ èŠããããŸãã ããŒã·ã£ã©ãŒã¯ããªããžã§ã¯ããå®è£ ããã€ã³ã¿ãŒãã§ã€ã¹ã®ããããã調ã¹ãããšã§ããªããžã§ã¯ããèå¥ããŸãã
ããšãã°ãããŒã·ã£ã©ãŒã¯ããããŒãžã ã³ãŒãã«æž¡ãããã€ã³ã¿ãŒãã§ã€ã¹ãã©ããããããã«ã¯ã©ã¹ ã©ãããŒã䜿çšããå¿ èŠããããšå€æããŸãã ã€ã³ã¿ãŒãã§ã€ã¹ãããŒã·ã£ã©ãŒãåããŠééãããšãããŒã·ã£ã©ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãæ¢ç¥ã®ãªããžã§ã¯ãããéä¿¡ãããŠãããã©ããã確èªããŸãã ãã®ãã§ãã¯ã¯ã次㮠2 ã€ã®ç¶æ³ã§çºçããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãä»ã®å Žæã® COM ã«æž¡ãããå¥ã®ãããŒãžã ãªããžã§ã¯ãã«ãã£ãŠå®è£ ãããŠããŸãã ããŒã·ã£ã©ãŒã¯ããããŒãžã ãªããžã§ã¯ãã«ãã£ãŠå ¬éãããŠããã€ã³ã¿ãŒãã§ã€ã¹ãç°¡åã«èå¥ã§ããå®è£ ãæäŸãããããŒãžã ãªããžã§ã¯ããšã€ã³ã¿ãŒãã§ã€ã¹ãç §åã§ããŸãã ãã®åŸããããŒãžã ãªããžã§ã¯ããã¡ãœããã«æž¡ãããã©ãããŒã¯å¿ èŠãããŸããã
æ¢ã«ã©ãããããŠãããªããžã§ã¯ãã¯ãã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããŠããŸãã ãããåœãŠã¯ãŸããã©ããã倿ããããã«ãããŒã·ã£ã©ãŒã¯ãªããžã§ã¯ãã«
IUnknownã€ã³ã¿ãŒãã§ã€ã¹ãç §äŒããè¿ãããã€ã³ã¿ãŒãã§ã€ã¹ããæ¢ã«ã©ãããããŠããä»ã®ãªããžã§ã¯ãã®ã€ã³ã¿ãŒãã§ã€ã¹ãšæ¯èŒããŸãã ã€ã³ã¿ãŒãã§ã€ã¹ãå¥ã®ã©ãããŒãšåãå Žåããªããžã§ã¯ãã¯åã ID ãæã¡ãæ¢åã®ã©ãããŒãã¡ãœããã«æž¡ãããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ãæ¢ç¥ã®ãªããžã§ã¯ãããã§ãªãå ŽåãããŒã·ã£ã©ãŒã¯æ¬¡ã®åŠçãè¡ããŸãã
ããŒã·ã£ã©ãŒã¯ã IProvideClassInfo2 ã€ã³ã¿ãŒãã§ã€ã¹ã®ãªããžã§ã¯ããç §äŒããŸãã æå®ãããå ŽåãããŒã·ã£ã©ãŒã¯ IProvideClassInfo2.GetGUID ããè¿ããã CLSID ã䜿çšããŠãã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããã³ã¯ã©ã¹ãèå¥ããŸãã CLSID ã䜿çšãããšãã¢ã»ã³ããªã以åã«ç»é²ãããŠããå ŽåãããŒã·ã£ã©ãŒã¯ã¬ãžã¹ããªããã©ãããŒãèŠã€ããããšãã§ããŸãã
ããŒã·ã£ã©ãŒã¯ã
IProvideClassInfoã€ã³ã¿ãŒãã§ã€ã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«å¯ŸããŠã¯ãšãªãå®è¡ããŸãã æå®ããå ŽåãããŒã·ã£ã©ãŒã¯ITypeInfoããè¿ãããã䜿çšããŠãã€ã³ã¿ãŒãã§ã€ã¹ãå ¬éããã¯ã©ã¹ã® CLSID ãæ±ºå®ããŸãã ããŒã·ã£ã©ãŒã¯ CLSID ã䜿çšããŠã©ãããŒã®ã¡ã¿ããŒã¿ãèŠã€ããããšãã§ããŸããããŒã·ã£ã©ãŒããŸã ã¯ã©ã¹ãèå¥ã§ããªãå Žåã¯ã ã€ã³ã¿ãŒãã§ã€ã¹ã System.__ComObject ãšããæ±çšã©ãã㌠ã¯ã©ã¹ã§ã©ããããŸãã
ããªã²ãŒãã«å¯Ÿããæ¢å®ã®ããŒã·ã£ãªã³ã°
ãããŒãžã ããªã²ãŒãã¯ãåŒã³åºãå ã®ã¡ã«ããºã ã«åºã¥ããŠãCOM ã€ã³ã¿ãŒãã§ã€ã¹ãŸãã¯é¢æ°ãã€ã³ã¿ãŒãšããŠããŒã·ã£ãªã³ã°ãããŸãã
ãã©ãããã©ãŒã åŒã³åºãã®å Žåãããªã²ãŒãã¯æ¢å®ã§ã¢ã³ãããŒãžé¢æ°ãã€ã³ã¿ãŒãšããŠããŒã·ã£ãªã³ã°ãããŸãã
COM çžäºéçšæ©èœã®å Žåãããªã²ãŒãã¯æ¢å®ã§
_Delegateåã® COM ã€ã³ã¿ãŒãã§ã€ã¹ãšããŠããŒã·ã£ãªã³ã°ãããŸãã_Delegateã€ã³ã¿ãŒãã§ã€ã¹ã¯ Mscorlib.tlb ã¿ã€ã ã©ã€ãã©ãªã§å®çŸ©ãããããªã²ãŒããåç §ããã¡ãœãããåŒã³åºãDelegate.DynamicInvoke ã¡ãœãããå«ãŸããŠããŸãã
次ã®è¡šã«ããããŒãžã ããªã²ãŒã ããŒã¿åã®ããŒã·ã£ãªã³ã° ãªãã·ã§ã³ã瀺ããŸãã MarshalAsAttribute屿§ã¯ãããªã²ãŒããããŒã·ã£ãªã³ã°ããããã®ããã€ãã®UnmanagedTypeåæå€ãæäŸããŸãã
| åæå | æªç®¡ç圢åŒã®èª¬æ |
|---|---|
| UnmanagedType.FunctionPtr | é管ç颿°ãã€ã³ã¿ãŒã |
| UnmanagedType.Interface | Mscorlib.tlb ã§å®çŸ©ãããŠãã _Delegateåã®ã€ã³ã¿ãŒãã§ã€ã¹ã |
DelegateTestInterfaceã®ã¡ãœããã COM ã¿ã€ã ã©ã€ãã©ãªã«ãšã¯ã¹ããŒãããã³ãŒãäŸã次ã«ç€ºããŸãã
ref (ãŸã㯠ByRef) ããŒã¯ãŒãã§ããŒã¯ãããããªã²ãŒãã®ã¿ã In/Out ãã©ã¡ãŒã¿ãŒãšããŠæž¡ãããããšã«æ³šæããŠãã ããã
using System;
using System.Runtime.InteropServices;
public interface DelegateTest {
void m1(Delegate d);
void m2([MarshalAs(UnmanagedType.Interface)] Delegate d);
void m3([MarshalAs(UnmanagedType.Interface)] ref Delegate d);
void m4([MarshalAs(UnmanagedType.FunctionPtr)] Delegate d);
void m5([MarshalAs(UnmanagedType.FunctionPtr)] ref Delegate d);
}
ã¿ã€ã ã©ã€ãã©ãªã®è¡šçŸ
importlib("mscorlib.tlb");
interface DelegateTest : IDispatch {
[id(âŠ)] HRESULT m1([in] _Delegate* d);
[id(âŠ)] HRESULT m2([in] _Delegate* d);
[id(âŠ)] HRESULT m3([in, out] _Delegate** d);
[id()] HRESULT m4([in] int d);
[id()] HRESULT m5([in, out] int *d);
};
ä»ã®ã¢ã³ãããŒãžé¢æ°ãã€ã³ã¿ãŒãéåç §ã§ããã®ãšåæ§ã«ã颿°ãã€ã³ã¿ãŒã¯éåç §ã§ããŸãã
ãã®äŸã§ã¯ã2 ã€ã®ããªã²ãŒãã UnmanagedType.FunctionPtrãšããŠããŒã·ã£ãªã³ã°ããããšãçµæã¯ int ãš intãžã®ãã€ã³ã¿ãŒã«ãªããŸãã ããªã²ãŒãåã¯ããŒã·ã£ãªã³ã°ãããŠãããããããã§ int ã¯ãã¡ã¢ãªå
ã®ããªã²ãŒãã®ã¢ãã¬ã¹ã§ãã void (void*) ãžã®ãã€ã³ã¿ãŒã衚ããŸãã ã€ãŸãããã®çµæã¯ 32 ãããã® Windows ã·ã¹ãã ã«åºæã§ããããã§ int ã¯é¢æ°ãã€ã³ã¿ãŒã®ãµã€ãºã衚ããŠããããã§ãã
Note
ã¢ã³ãããŒãž ã³ãŒãã«ãã£ãŠä¿æãããŠãããããŒãžã ããªã²ãŒããžã®é¢æ°ãã€ã³ã¿ãŒãžã®åç §ã¯ãå ±éèšèªã©ã³ã¿ã€ã ããããŒãžã ãªããžã§ã¯ãã«å¯ŸããŠã¬ããŒãž ã³ã¬ã¯ã·ã§ã³ãå®è¡ããããšã劚ãããã®ã§ã¯ãããŸããã
ããšãã°ãcb ã¡ãœããã«æž¡ãããSetChangeHandler ãªããžã§ã¯ããžã®åç
§ããcb ã¡ãœããã®æå¹æéãè¶
ããŠTestç¶æãããªããããæ¬¡ã®ã³ãŒãã¯æ£ãããããŸããã
cb ãªããžã§ã¯ããã¬ããŒãž ã³ã¬ã¯ã·ã§ã³ããããšãSetChangeHandlerã«æž¡ããã颿°ãã€ã³ã¿ãŒã¯ç¡å¹ã«ãªããŸãã
public class ExternalAPI {
[DllImport("External.dll")]
public static extern void SetChangeHandler(
[MarshalAs(UnmanagedType.FunctionPtr)]ChangeDelegate d);
}
public delegate bool ChangeDelegate([MarshalAs(UnmanagedType.LPWStr) string S);
public class CallBackClass {
public bool OnChange(string S){ return true;}
}
internal class DelegateTest {
public static void Test() {
CallBackClass cb = new CallBackClass();
// Caution: The following reference on the cb object does not keep the
// object from being garbage collected after the Main method
// executes.
ExternalAPI.SetChangeHandler(new ChangeDelegate(cb.OnChange));
}
}
äºæããªãã¬ããŒãž ã³ã¬ã¯ã·ã§ã³ãè£æ£ããããã«ãåŒã³åºãå
ã¯ãã¢ã³ãããŒãžé¢æ°ãã€ã³ã¿ãŒã®äœ¿çšäžã¯ cb ãªããžã§ã¯ããæå¹ã®ãŸãŸä¿æãããããã«ããå¿
èŠããããŸãã å¿
èŠã«å¿ããŠã次ã®äŸã«ç€ºãããã«ã颿°ãã€ã³ã¿ãŒãäžèŠã«ãªã£ããšãã«ã¢ã³ãããŒãž ã³ãŒãã«ãããŒãžã ã³ãŒãã«éç¥ãããããšãã§ããŸãã
internal class DelegateTest {
CallBackClass cb;
// Called before ever using the callback function.
public static void SetChangeHandler() {
cb = new CallBackClass();
ExternalAPI.SetChangeHandler(new ChangeDelegate(cb.OnChange));
}
// Called after using the callback function for the last time.
public static void RemoveChangeHandler() {
// The cb object can be collected now. The unmanaged code is
// finished with the callback function.
cb = null;
}
}
å€åã«å¯Ÿããæ¢å®ã®ããŒã·ã£ãªã³ã°
æŽæ°ãæµ®åå°æ°ç¹æ°ãªã©ã®ã»ãšãã©ã®å€å㯠blittable ã§ãããããŒã·ã£ãªã³ã°ã¯å¿ èŠãããŸããã ãã®ä»ã® non-blittable åã¯ããããŒãžãããã³ã¢ã³ãããŒãžã ã¡ã¢ãªã«é¡äŒŒããªã衚çŸããããããŒã·ã£ãªã³ã°ãå¿ èŠã§ãã ããã§ãä»ã®åã§ã¯ãçžäºéçšå¢çãè¶ããŠæç€ºçãªæžåŒèšå®ãå¿ èŠã§ãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãæ¬¡ã®æžåŒèšå®ãããå€åã«ã€ããŠèª¬æããŸãã
ãã®ãããã¯ã§ã¯ãæžåŒèšå®ãããåã®èª¬æã«å ããŠãéåžžãšã¯ç°ãªãããŒã·ã£ãªã³ã°åäœãæã€ ã·ã¹ãã å€å ãèå¥ããŸãã
æžåŒèšå®ãããåã¯ãã¡ã¢ãªå ã®ã¡ã³ããŒã®ã¬ã€ã¢ãŠããæç€ºçã«å¶åŸ¡ããæ å ±ãå«ãè€ååã§ãã ã¡ã³ã㌠ã¬ã€ã¢ãŠãæ å ±ã¯ã StructLayoutAttribute 屿§ã䜿çšããŠæäŸãããŸãã ã¬ã€ã¢ãŠãã«ã¯ã次㮠LayoutKind åæå€ã®ãããããæå®ã§ããŸãã
LayoutKind.Auto
å ±éèšèªã©ã³ã¿ã€ã ããå¹çãé«ããããã«åã®ã¡ã³ããŒãèªç±ã«äžŠã¹æ¿ãå¯èœã§ããããšã瀺ããŸãã ãã ããã¢ã³ãããŒãžã ã³ãŒãã«å€åãæž¡ããããšãã¡ã³ããŒã®ã¬ã€ã¢ãŠãã¯äºæž¬å¯èœã«ãªããŸãã ãã®ãããªæ§é äœãããŒã·ã£ãªã³ã°ããããšãããšãèªåçã«äŸå€ãçºçããŸãã
LayoutKind.Sequential
åã®ã¡ã³ããŒãããããŒãžãåå®çŸ©ã«è¡šç€ºãããé åºãšåãé åºã§ã¢ã³ãããŒãž ã¡ã¢ãªã«é 眮ãããããšã瀺ããŸãã
LayoutKind.Explicit
åãã£ãŒã«ãã«æå®ããã FieldOffsetAttribute ã«åŸã£ãŠã¡ã³ããŒãã¬ã€ã¢ãŠããããããšã瀺ããŸãã
ãã©ãããã©ãŒã åŒã³åºãã§äœ¿çšãããå€å
次ã®äŸã§ã¯ã Point åãš Rect å㯠ãStructLayoutAttribute ã䜿çšããŠã¡ã³ã㌠ã¬ã€ã¢ãŠãæ
å ±ãæäŸããŸãã
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> Public Structure Point
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Explicit)> Public Structure Rect
<FieldOffset(0)> Public left As Integer
<FieldOffset(4)> Public top As Integer
<FieldOffset(8)> Public right As Integer
<FieldOffset(12)> Public bottom As Integer
End Structure
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
public int x;
public int y;
}
[StructLayout(LayoutKind.Explicit)]
public struct Rect {
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
}
ã¢ã³ãããŒãž ã³ãŒãã«ããŒã·ã£ãªã³ã°ãããšããããã®æžåŒèšå®ãããå㯠C ã¹ã¿ã€ã«ã®æ§é äœãšããŠããŒã·ã£ãªã³ã°ãããŸãã ããã«ãããæ§é äœåŒæ°ãæã€ã¢ã³ãããŒãž API ãç°¡åã«åŒã³åºãæ¹æ³ãæäŸãããŸãã ããšãã°ã POINT ããã³ RECT æ§é äœã¯ã次ã®ããã« Microsoft Windows API PtInRect 颿°ã«æž¡ãããšãã§ããŸãã
BOOL PtInRect(const RECT *lprc, POINT pt);
次ã®ãã©ãããã©ãŒã åŒã³åºãå®çŸ©ã䜿çšããŠæ§é äœãæž¡ãããšãã§ããŸãã
Friend Class NativeMethods
Friend Declare Auto Function PtInRect Lib "User32.dll" (
ByRef r As Rect, p As Point) As Boolean
End Class
internal static class NativeMethods
{
[DllImport("User32.dll")]
internal static extern bool PtInRect(ref Rect r, Point p);
}
ã¢ã³ãããŒãž API ã¯Rectãžã®ãã€ã³ã¿ãŒã颿°ã«æž¡ãããšãæ³å®ãããŠãããããRECTå€åãåç
§æž¡ãããå¿
èŠããããŸãã
Pointå€åã¯ãã¢ã³ãããŒãž API ãã¹ã¿ãã¯ã§POINTãæž¡ãããããšãæ³å®ããŠããããã倿ž¡ããããŸãã ãã®åŸ®åŠãªéãã¯éåžžã«éèŠã§ãã åç
§ã¯ããã€ã³ã¿ãŒãšããŠã¢ã³ãããŒãž ã³ãŒãã«æž¡ãããŸãã å€ã¯ãã¹ã¿ãã¯äžã®ã¢ã³ãããŒãž ã³ãŒãã«æž¡ãããŸãã
Note
æžåŒèšå®ãããåãæ§é äœãšããŠããŒã·ã£ãªã³ã°ãããŠããå Žåããã®åå ã®ãã£ãŒã«ãã«ã®ã¿ã¢ã¯ã»ã¹ã§ããŸãã åã«ã¡ãœãããããããã£ããŸãã¯ã€ãã³ããããå Žåãã¢ã³ãããŒãž ã³ãŒãããã¢ã¯ã»ã¹ã§ããŸããã
ã¯ã©ã¹ã¯ãåºå®ã¡ã³ã㌠ã¬ã€ã¢ãŠããããå ŽåãC ã¹ã¿ã€ã«ã®æ§é äœãšããŠã¢ã³ãããŒãž ã³ãŒãã«ããŒã·ã£ãªã³ã°ããããšãã§ããŸãã ã¯ã©ã¹ã®ã¡ã³ã㌠ã¬ã€ã¢ãŠãæ å ±ãã StructLayoutAttribute 屿§ãšå ±ã«æäŸãããŸãã åºå®ã¬ã€ã¢ãŠãã®å€åãšåºå®ã¬ã€ã¢ãŠãã®ã¯ã©ã¹ã®äž»ãªéãã¯ãã¢ã³ãããŒãžã ã³ãŒãã«ããŒã·ã£ãªã³ã°ããæ¹æ³ã§ãã å€å㯠(ã¹ã¿ãã¯äžã®) å€ã«ãã£ãŠæž¡ããããããåŒã³åºãå ã«ãã£ãŠåã®ã¡ã³ããŒã«å ãããã倿Žã¯åŒã³åºãå ã«ã¯è¡šç€ºãããŸããã åç §åã¯åç §ã«ãã£ãŠæž¡ãããŸã (åãžã®åç §ã¯ã¹ã¿ãã¯ã§æž¡ãããŸã)ããããã£ãŠãåŒã³åºãå ã«ãã£ãŠåã® blittable åã¡ã³ããŒã«å ãããããã¹ãŠã®å€æŽãåŒã³åºãå ã«ãã£ãŠè¡šç€ºãããŸãã
Note
åç §åã« blittable 以å€ã®åã®ã¡ã³ããŒãããå Žåãå€æã¯ 2 åå¿ èŠã§ããæåã«åŒæ°ãã¢ã³ãããŒãžåŽã«æž¡ããããšããšãåŒã³åºããã 2 åç®ãè¿ããããšãã§ãã ãã®ãªãŒããŒããããå¢å ãããããåŒã³åºãå ãåŒã³åºãå ã«ãã£ãŠè¡ããã倿Žã衚瀺ããå Žåã¯ãIn/Out ãã©ã¡ãŒã¿ãŒãæç€ºçã«åŒæ°ã«é©çšããå¿ èŠããããŸãã
次ã®äŸã§ã¯ã SystemTime ã¯ã©ã¹ã¯ã·ãŒã±ã³ã·ã£ã« ã¡ã³ã㌠ã¬ã€ã¢ãŠããæã¡ãWindows API GetSystemTime 颿°ã«æž¡ãããšãã§ããŸãã
<StructLayout(LayoutKind.Sequential)> Public Class SystemTime
Public wYear As System.UInt16
Public wMonth As System.UInt16
Public wDayOfWeek As System.UInt16
Public wDay As System.UInt16
Public wHour As System.UInt16
Public wMinute As System.UInt16
Public wSecond As System.UInt16
Public wMilliseconds As System.UInt16
End Class
[StructLayout(LayoutKind.Sequential)]
public class SystemTime {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
GetSystemTime颿°ã¯æ¬¡ã®ããã«å®çŸ©ãããŸãã
void GetSystemTime(SYSTEMTIME* SystemTime);
GetSystemTimeã®åçã®ãã©ãããã©ãŒã åŒã³åºãå®çŸ©ã¯æ¬¡ã®ãšããã§ãã
Friend Class NativeMethods
Friend Declare Auto Sub GetSystemTime Lib "Kernel32.dll" (
ByVal sysTime As SystemTime)
End Class
internal static class NativeMethods
{
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
internal static extern void GetSystemTime(SystemTime st);
}
SystemTimeã¯å€åã§ã¯ãªãã¯ã©ã¹ã§ãããããSystemTimeåŒæ°ã¯åç
§åŒæ°ãšããŠåæå®ãããŠããªãããšã«æ³šæããŠãã ããã å€åãšã¯ç°ãªããã¯ã©ã¹ã¯åžžã«åç
§ã«ãã£ãŠæž¡ãããŸãã
次ã®ã³ãŒãäŸã¯ãPoint ãšããã¡ãœãããæã€å¥ã®SetXY ã¯ã©ã¹ã瀺ããŠããŸãã åã«ã¯ã·ãŒã±ã³ã·ã£ã« ã¬ã€ã¢ãŠãããããããã¢ã³ãããŒãž ã³ãŒãã«æž¡ããŠæ§é äœãšããŠããŒã·ã£ãªã³ã°ã§ããŸãã ãã ãããªããžã§ã¯ããåç
§æž¡ãã§ãã£ãŠãã SetXY ã¡ã³ããŒã¯ã¢ã³ãããŒãž ã³ãŒãããåŒã³åºãããšãã§ããŸããã
<StructLayout(LayoutKind.Sequential)> Public Class Point
Private x, y As Integer
Public Sub SetXY(x As Integer, y As Integer)
Me.x = x
Me.y = y
End Sub
End Class
[StructLayout(LayoutKind.Sequential)]
public class Point {
int x, y;
public void SetXY(int x, int y){
this.x = x;
this.y = y;
}
}
COM çžäºéçšæ©èœã§äœ¿çšãããå€å
æžåŒèšå®ãããåã¯ãCOM çžäºéçšã¡ãœããåŒã³åºãã«ãæž¡ãããšãã§ããŸãã å®éãã¿ã€ã ã©ã€ãã©ãªã«ãšã¯ã¹ããŒããããšãå€åã¯èªåçã«æ§é äœã«å€æãããŸãã æ¬¡ã®äŸã«ç€ºãããã«ã Point å€åã¯ã Pointãšããååã®åå®çŸ© (typedef) ã«ãªããŸãã ã¿ã€ã ã©ã€ãã©ãªå
ã®å¥ã®å Žæã«ãã Point å€åãžã®åç
§ã¯ãã¹ãŠã Point typedef ã«çœ®ãæããããŸãã
åã©ã€ãã©ãªã®è¡šçŸ
typedef struct tagPoint {
int x;
int y;
} Point;
interface _Graphics {
âŠ
HRESULT SetPoint ([in] Point p)
HRESULT SetPointRef ([in,out] Point *p)
HRESULT GetPoint ([out,retval] Point *p)
}
COM ã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠããŒã·ã£ãªã³ã°ãããšãã«ãå€ãšãã©ãããã©ãŒã åŒã³åºããžã®åç
§ãããŒã·ã£ãªã³ã°ããããã«äœ¿çšãããã®ãšåãèŠåã䜿çšãããŸãã ããšãã°ãPointå€åã®ã€ã³ã¹ã¿ã³ã¹ã .NET ã©ã³ã¿ã€ã ãã COM ã«æž¡ããããšãPointã¯å€æž¡ããããŸãã
Pointå€åãåç
§æž¡ãã®å ŽåãPointãžã®ãã€ã³ã¿ãŒãã¹ã¿ãã¯ã«æž¡ãããŸãã çžäºéçšããŒã·ã£ã©ãŒã§ã¯ãã©ã¡ãã®æ¹åã«ã€ããŠããããé«ãã¬ãã«ã®éæ¥åç
§ (Point **) ã¯ãµããŒããããŠããŸããã
Note
ãšã¯ã¹ããŒããããã¿ã€ã ã©ã€ãã©ãªã¯æç€ºçãªã¬ã€ã¢ãŠãã衚ãããšãã§ããªãããã LayoutKind åæå€ã Explicit ã«èšå®ãããŠããæ§é äœã¯ COM çžäºéçšæ©èœã§ã¯äœ¿çšã§ããŸããã
ã·ã¹ãã ã®å€å
Systemåå空éã«ã¯ãã©ã³ã¿ã€ã ããªããã£ãåã®ããã¯ã¹åããã圢åŒã衚ãè€æ°ã®å€åããããŸãã ããšãã°ãå€å System.Int32 æ§é äœã¯ãããã¯ã¹åããã 圢åŒã®ELEMENT_TYPE_I4ã衚ããŸãã ä»ã®æžåŒèšå®ãããåãšåæ§ã«ããããã®åãæ§é äœãšããŠããŒã·ã£ãªã³ã°ãã代ããã«ãããã¯ã¹åãããããªããã£ãåãšåãæ¹æ³ã§ããŒã·ã£ãªã³ã°ããŸãã ãããã£ãŠãSystem.Int32 㯠long åã® 1 ã€ã®ã¡ã³ããŒãå«ãæ§é äœãšããŠã§ã¯ãªããELEMENT_TYPE_I4ãšããŠããŒã·ã£ãªã³ã°ãããŸãã æ¬¡ã®è¡šã«ãããªããã£ãåã®ããã¯ã¹å衚çŸã§ãã System åå空éã®å€åã®äžèЧã瀺ããŸãã
| ã·ã¹ãã å€å | èŠçŽ ã¿ã€ã |
|---|---|
| System.Boolean | ELEMENT_TYPE_BOOLEAN |
| System.SByte | ELEMENT_TYPE_I1 |
| System.Byte | ELEMENT_TYPE_UI1 |
| System.Char | ELEMENT_TYPE_CHAR |
| System.Int16 | ELEMENT_TYPE_I2 |
| System.UInt16 | ELEMENT_TYPE_U2 |
| System.Int32 | ELEMENT_TYPE_I4 |
| System.UInt32 | ELEMENT_TYPE_U4 |
| System.Int64 | ELEMENT_TYPE_I8 |
| System.UInt64 | ELEMENT_TYPE_U8 |
| System.Single | ELEMENT_TYPE_R4 |
| System.Double | ELEMENT_TYPE_R8 |
| System.String | ELEMENT_TYPE_STRING |
| System.IntPtr | ELEMENT_TYPE_I |
| System.UIntPtr | ELEMENT_TYPE_U |
Systemåå空éã®ãã®ä»ã®å€åã®åŠçæ¹æ³ã¯ç°ãªããŸãã ã¢ã³ãããŒãžã ã³ãŒãã§ã¯ãããã®åã®åœ¢åŒãæ¢ã«ç¢ºç«ãããŠãããããããŒã·ã£ã©ãŒã«ã¯ãããããããŒã·ã£ãªã³ã°ããããã®ç¹å¥ãªèŠåããããŸãã æ¬¡ã®è¡šã¯ãSystem åå空éã®ç¹æ®ãªå€åãšãããã«å¯ŸããŠããŒã·ã£ãªã³ã°ãããã¢ã³ãããŒãžåãäžèЧããŸãã
| ã·ã¹ãã å€å | IDL ã®çš®é¡ |
|---|---|
| System.DateTime | DATE |
| System.Decimal | DECIMAL |
| System.Guid | GUID |
| System.Drawing.Color | OLE_COLOR |
次ã®ã³ãŒãã¯ãStdole2 ã¿ã€ã ã©ã€ãã©ãªã®ã¢ã³ãããŒãžå DATEã GUIDã DECIMALãããã³ OLE_COLOR ã®å®çŸ©ã瀺ããŠããŸãã
ã¿ã€ã ã©ã€ãã©ãªã®è¡šçŸ
typedef double DATE;
typedef DWORD OLE_COLOR;
typedef struct tagDEC {
USHORT wReserved;
BYTE scale;
BYTE sign;
ULONG Hi32;
ULONGLONG Lo64;
} DECIMAL;
typedef struct tagGUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[ 8 ];
} GUID;
次ã®ã³ãŒãã¯ããããŒãžã IValueTypes ã€ã³ã¿ãŒãã§ã€ã¹ã®å¯Ÿå¿ããå®çŸ©ã瀺ããŠããŸãã
Public Interface IValueTypes
Sub M1(d As System.DateTime)
Sub M2(d As System.Guid)
Sub M3(d As System.Decimal)
Sub M4(d As System.Drawing.Color)
End Interface
public interface IValueTypes {
void M1(System.DateTime d);
void M2(System.Guid d);
void M3(System.Decimal d);
void M4(System.Drawing.Color d);
}
ã¿ã€ã ã©ã€ãã©ãªã®è¡šçŸ
[âŠ]
interface IValueTypes : IDispatch {
HRESULT M1([in] DATE d);
HRESULT M2([in] GUID d);
HRESULT M3([in] DECIMAL d);
HRESULT M4([in] OLE_COLOR d);
};