live2
live2

Reputation: 4265

C# DllImport crashes unexpectedly

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

Answers (2)

live2
live2

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

OriBS
OriBS

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

Related Questions