#副標=使用C#Builder和設計樣例 #大標=如何在.NET中管理Unmanaged程式碼 作者=李維 ============================== function TMySimpleCOM. GetSystemTime: WideString; begin Result := DateTimeToStr(Now); end; initialization TAutoObjectFactory.Create(ComServer, TMySimpleCOM, Class_MySimpleCOM, ciMultiInstance, tmApartment); ============================== ============================== [DllImport("aviPlayer.dll", CharSet=CharSet.Ansi)] public static extern void PlayAVI(); ============================== ============================== … using PMySimpleCOM; using System.Runtime.InteropServices; … private void btnCallCOM_Click(object sender, System.EventArgs e) { MySimpleCOMClass aObj; aObj = new MySimpleCOMClass(); this.textBox1.Text = aObj.GetSystemTime(); } [DllImport("aviPlayer.dll", CharSet=CharSet.Ansi)] public static extern void PlayAVI(); private void btnCallDll_Click(object sender, System.EventArgs e) { PlayAVI(); } ============================== ============================== using System; using System.Runtime.InteropServices; namespace CSMainLoader { /// /// Summary description for Class. /// public class TaviPlayerWrapper { static uint SEM_NOOPENFILEERRORBOX = 0x8000; private int FDllHandle; private const String FDllFileName = "aviPlayer.dll"; public TaviPlayerWrapper() { // // TODO: Add constructor logic here // FDllHandle = SafeLoadLibrary(FDllFileName, SEM_NOOPENFILEERRORBOX); } [DllImport(FDllFileName, CharSet = CharSet.Ansi, SetLastError = true, EntryPoint = "DoInit")] public static extern void DoInit(); public virtual void DoDllWorks() { DoInit(); } [DllImport(FDllFileName, CharSet = CharSet.Ansi, SetLastError = true, EntryPoint = "DoFinalize")] public static extern void DoFinalize(); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, EntryPoint = "FreeLibrary")] public static extern bool FreeLibrary(int HModule); public virtual void DoCleanup() { DoFinalize(); FreeLibrary(FDllHandle); } [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, EntryPoint = "SetErrorMode")] public static extern uint SetErrorMode(uint uMode); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, EntryPoint = "LoadLibrary")] public static extern int LoadLibrary(String sDllName); private int SafeLoadLibrary(String sDllName, uint ErrorMode) { int iResult; uint uiOldMode; uiOldMode = SetErrorMode(ErrorMode); try { iResult = LoadLibrary(sDllName); } finally { SetErrorMode(uiOldMode); } return iResult; } } } ============================== ============================== using System; using System.Collections; namespace CSMainLoader { /// /// Summary description for Class. /// public class TDllManager : IDisposable { public delegate void TFinalizeNotify(); private bool bDisposed = false; private TFinalizeNotify FNotifies; ~TDllManager() { Dispose(false); } //IDisposable Interface public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected void Dispose(bool bDispoing) { if (!bDisposed) { CallNotifies(); } bDisposed = true; } protected void CallNotifies() { FNotifies.DynamicInvoke(null); } public void RegisterFinalizeNotify(TFinalizeNotify fn) { FNotifies = FNotifies + fn; } public void UnregisterFinalizeNotify(TFinalizeNotify fn) { FNotifies = FNotifies - fn; } } } ============================== ============================== exports DoInit, DoFinalize; //PlayAVI; ============================== ============================== procedure DoInit; stdcall; begin Form1 := TForm1.Create(nil); Form1.Show; end; procedure DoFinalize; stdcall; begin if Assigned(Form1) then begin Form1.MediaPlayer1.Close; FreeAndNil(Form1); end; end; ============================== ============================== private void button1_Click(object sender, System.EventArgs e) { aDllManager = new TDllManager(); aWrapper = new TaviPlayerWrapper(); aFN = new TDllManager.TFinalizeNotify(aWrapper.DoCleanup); aDllManager.RegisterFinalizeNotify(aFN); aWrapper.DoDllWorks(); } private void button2_Click(object sender, System.EventArgs e) { System.Threading.Thread.Sleep(3000); aDllManager.Dispose(); } ============================== ============================== public TDllManager() { AppDomain ad = AppDomain.CurrentDomain; ad.ProcessExit += new System.EventHandler(OnExitEvent); } protected virtual void OnExitEvent(object sender, System.EventArgs e) { Dispose(true); } ==============================