PJSUA2 C++ program has been wrapped with SWIG to C# and using within .NET application as DLL library. Everything works fine until the application closes. A method ep.libdestroy() invokes Dispose(), where pjsua2PINVOKE.delete_LogWriter(swigCPtr) is. This operation throws an exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I have read about problem with unmanaged memeory in DLL, when the object in managed code have reference to struct created in unmanaged code. In .NET app, an object for LogWriter is created and set in way based on sample for PJSUA2 C#:
(...)
MyLogWriter writer = new MyLogWriter();
epConfig = new EpConfig();
epConfig.logConfig.writer = writer;
(...)
When app is going to close, LogWriter object throws System.AccessViolationException in code line pjsua2PINVOKE.delete_LogWriter(swigCPtr); The code which I use it was generated by SWIG and it showed as below:
~LogWriter() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
}
protected virtual void Dispose(bool disposing) {
lock(this) {
if (swigCPtr.Handle != global::System.IntPtr.Zero) {
if (swigCMemOwn) {
swigCMemOwn = false;
pjsua2PINVOKE.delete_LogWriter(swigCPtr);
}
swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
}
}
}
I've tried to close app with Dispose overrived method with: global::System.GC.SuppressFinalize(this) but this was not helped:
public void Dispose() {
Dispose(true);
global::System.GC.SuppressFinalize(this);
}
If I don't set the object to a variable:
\\epConfig.logConfig.writer = writer;
the problem is disappeared, but I haven't got a LogWriter functionality. Could you help to provide me to solve this problem?
I have found the solution of this problem in the last release of PJSIP 2.13. There was a trick implemented in the sample of app programmed with swig wrapping to C#:
~MyLogWriter()
{
Console.WriteLine("*** MyLogWriter is being deleted");
// A bit hack here.
// Detach the native instance as the library deletes it automatically upon libDestroy().
swigCMemOwn = false;
}