Reputation: 4265
I have a C# Application with a C++ component. I am communicate with DllImport
between the modules. The Application works for many days without a problem and crash sometime unexpectedly.
[DllImport("recorder", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr start_recording();
Is it possible to run the C++ part in a protected container so that not the whole application crashes?
Event Viewer
Application Error
Faulting application name: Recorder.exe, version: 1.0.0.0, time stamp: 0x59eef7cb
Faulting module name: avformat-57.dll, version: 57.71.100.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x00000000000d7e7f
Faulting process id: 0x186c
Faulting application start time: 0x01d3620b7e41ef96
Faulting application path: C:\Test\Recorder.exe
Faulting module path: C:\Test\avformat-57.dll
Report Id: 3fde49fc-d2ed-11e7-bf5c-002590abb7d4
.NET Runtime
Application: Recorder.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: exception code c0000005, exception address 000007FEEA407E7F
Upvotes: 4
Views: 944
Reputation: 4265
Here you can find more Informations for Interprocess Communications
I have decided to use NamedPipes is very fast and i can communicate in both directions.
C++ Example
cout << "Connecting to pipe..." << endl;
// Open the named pipe
// Most of these parameters aren't very relevant for pipes.
HANDLE pipe = CreateFile(
L"\\\\.\\pipe\\MyServerPipe",
GENERIC_READ, // only need read access
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
//NULL,
NULL
);
if (pipe == INVALID_HANDLE_VALUE) {
cout << "Failed to connect to pipe." << endl;
// look up error code here using GetLastError()
system("pause");
return 1;
}
cout << "Reading data from pipe..." << endl;
// The read operation will block until there is data to read
char buffer[128];
DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
127 * sizeof(char), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);
if (result) {
buffer[numBytesRead / sizeof(char)] = '\0'; // null terminate the string
cout << "Number of bytes read: " << numBytesRead << endl;
//wcout << "Message: " << buffer << endl;
//wstring ws(buffer);
//string str(ws.begin(), ws.end());
cout << "Test:" << buffer << endl;
}
else {
wcout << "Failed to read data from the pipe." << endl;
}
// Close our pipe handle
CloseHandle(pipe);
//wcout << "Done." << endl;
system("pause");
return 0;
C# Get all available Pipes
var listOfPipes = System.IO.Directory.GetFiles(@"\\.\pipe\")
C# Example
using (var pipeServer = new NamedPipeServerStream("MyServerPipe", PipeDirection.InOut))
{
Console.WriteLine("NamedPipeServerStream object created.");
// Wait for a client to connect
Console.Write("Waiting for client connection...");
pipeServer.WaitForConnection();
Console.WriteLine("Client connected.");
try
{
using (var bw = new BinaryWriter(pipeServer))
{
var data = Encoding.ASCII.GetBytes("SendInformation data1 data2 data3");
//var data = Encoding.ASCII.GetBytes("Start\r\n");
bw.Write(data);
}
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
Upvotes: 0
Reputation: 732
Generally, there are some conditions which will always cause a process to exit and you have nothing to do with it.
While you can handle some errors with catching exceptions, setting signal handler, or just fixing the bug, this will fix only a specific case, and will not give you a general solution, and it is possible you don't have control over the module at all.
The common solution in such a case is to separate the module into a different proxy process, which will communicate with your own application.
Upvotes: 2