public LibsnesApi(string dllPath) { InstanceName = "libsneshawk_" + Guid.NewGuid().ToString(); var pipeName = InstanceName; mmf = MemoryMappedFile.CreateNew(pipeName, 1024 * 1024); mmva = mmf.CreateViewAccessor(); mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref mmvaPtr); pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024 * 1024, 1024); instanceDll = new InstanceDll(dllPath); var dllinit = (DllInit)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("DllInit"), typeof(DllInit)); dllinit(pipeName); //TODO - start a thread to wait for process to exit and gracefully handle errors? how about the pipe? pipe.WaitForConnection(); rbuf = new IPCRingBuffer(); wbuf = new IPCRingBuffer(); rbuf.Allocate(1024); wbuf.Allocate(1024); rbufstr = new IPCRingBufferStream(rbuf); wbufstr = new IPCRingBufferStream(wbuf); rstream = new SwitcherStream(); wstream = new SwitcherStream(); rstream.SetCurrStream(pipe); wstream.SetCurrStream(pipe); brPipe = new BinaryReader(rstream); bwPipe = new BinaryWriter(wstream); WritePipeMessage(eMessage.eMessage_SetBuffer); bwPipe.Write(1); WritePipeString(rbuf.Id); WritePipeMessage(eMessage.eMessage_SetBuffer); bwPipe.Write(0); WritePipeString(wbuf.Id); bwPipe.Flush(); }
public LibsnesApi(string exePath) { //make sure we've checked this exe for OKness.. the dry run should keep us from freezing up or crashing weirdly if the external process isnt correct if (!okExes.Contains(exePath)) { bool ok = DryRun(exePath); if (!ok) { throw new InvalidOperationException(string.Format("Couldn't launch {0} to run SNES core. Not sure why this would have happened. Try redownloading BizHawk first.", Path.GetFileName(exePath))); } okExes.Add(exePath); } InstanceName = "libsneshawk_" + Guid.NewGuid().ToString(); #if DEBUG //use this to get a debug console with libsnes output InstanceName = "console-" + InstanceName; #endif var pipeName = InstanceName; mmf = MemoryMappedFile.CreateNew(pipeName, 1024 * 1024); mmva = mmf.CreateViewAccessor(); mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref mmvaPtr); pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024 * 1024, 1024); //slim chance this might be useful sometimes: //http://stackoverflow.com/questions/2590334/creating-a-cross-process-eventwaithandle //create an event for the child process to monitor with a watchdog, to make sure it terminates when the emuhawk process terminates. //NOTE: this is alarming! for some reason .net releases this event when it gets finalized, instead of when i (dont) dispose it. bool createdNew; watchdogEvent = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset, InstanceName + "-event", out createdNew); process = new Process(); process.StartInfo.WorkingDirectory = Path.GetDirectoryName(exePath); process.StartInfo.FileName = exePath; process.StartInfo.Arguments = pipeName; process.StartInfo.ErrorDialog = true; process.Start(); //TODO - start a thread to wait for process to exit and gracefully handle errors? how about the pipe? pipe.WaitForConnection(); rbuf = new IPCRingBuffer(); wbuf = new IPCRingBuffer(); rbuf.Allocate(1024); wbuf.Allocate(1024); rbufstr = new IPCRingBufferStream(rbuf); wbufstr = new IPCRingBufferStream(wbuf); rstream = new SwitcherStream(); wstream = new SwitcherStream(); rstream.SetCurrStream(pipe); wstream.SetCurrStream(pipe); brPipe = new BinaryReader(rstream); bwPipe = new BinaryWriter(wstream); WritePipeMessage(eMessage.eMessage_SetBuffer); bwPipe.Write(1); WritePipeString(rbuf.Id); WritePipeMessage(eMessage.eMessage_SetBuffer); bwPipe.Write(0); WritePipeString(wbuf.Id); bwPipe.Flush(); }