I'm writing a DLL in C# that is called from Delphi using dllexport.
The basics is very simple and works, but I wanted to expose a function that returns fills a string with specific message (not returning a string). The way I'm doing it is that the Delphi sends the function a pointer of type wide string (LPWSTR) and I fill it. This works well. However, when I do it, I need to free the memory and this is where I'm not sure I did the right thing.
The DLL is build in one class that implement IDisposable. This is because I need to free the memory after the function executes.
Here is the class and this one function.
In order to release the memory I allocate, I declare a global static intPtr, which I release as dispose. Here is the code.
Would be happy to get any feedback
namespace simpleDLL
{
public class Test : IDisposable
{
public delegate int prog(int i);
static IntPtr s_copy;
bool disposed = false;
[DllExport("getString", CallingConvention = CallingConvention.Cdecl)]
public static int getString(out IntPtr s, [MarshalAs(UnmanagedType.LPWStr)] string str)
{
s_copy = (IntPtr)Marshal.StringToHGlobalUni(str);
s = s_copy;
return str.Length;
}
public void Dispose()
{
Dispose(true);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
Marshal.FreeHGlobal(s_copy);
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
~Test()
{
Dispose(false);
}
}
Related
Following is a stripped-down version of c# code, which helps to capture the PrintScreen key. This work as I expected and tested.
Question: I am aware of deterministic destruction/disposal pattern, which I started to draft as below. However, I need some expert advice to complete my dispose and finalize method. Any advise ?
public class RegisterPrintKey : IDisposable
{
public delegate void HotKeyPass();
public event HotKeyPass HotKey;
private IntPtr m_WindowHandle = IntPtr.Zero;
private MKEY m_ModKey = MKEY.MOD_CONTROL;
private Keys m_Keys = Keys.A;
private HotKeyWndProc m_HotKeyWnd = new HotKeyWndProc();
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr wnd, int id, MKEY mode, Keys vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr wnd, int id);
private class HotKeyWndProc : NativeWindow
{
public int m_WParam = 10000;
public HotKeyPass m_HotKeyPass;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312 && m.WParam.ToInt32() == m_WParam)
{
if (m_HotKeyPass != null) m_HotKeyPass.Invoke();
}
base.WndProc(ref m);
}
}
private bool hasDisposed = false;
protected virtual void Dispose(bool dispose)
{
if (hasDisposed) return;
if (dispose)
{
//release objects owned by this instance
HotKey = null;
hasDisposed=true;
}
m_WindowHandle = IntPtr.Zero; // I presume this is not required.
m_Keys = null; //Do i need to dispose this or relay on stack ( clean up when thread unwind its stack)
m_ModKey = null;
m_HotKeyWnd.DestroyHandle();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~RegisterPrintKey()
{
Dispose(false);
}
}
public enum MKEY
{
MOD_ALT = 0x0001,
MOD_CONTROL = 0x0002,
MOD_SHIFT = 0x0004,
MOD_WIN = 0x0008,
}
Some suggestions on your code
public class RegisterPrintKey : IDisposable {
...
// This class can allocate the Window Handle resource (HWND)
private class HotKeyWndProc : NativeWindow {
}
// Explicit resource (HWND) allocation
private HotKeyWndProc m_HotKeyWnd = new HotKeyWndProc();
// I'd rather make a property from your "hasDisposed" field:
// - it's make easier to check instance's state (esp. while debugging)
// - IsDisposed is more popular name for this
public Boolean IsDisposed {
get;
protected set; // <- or even "private set"
}
protected virtual void Dispose(Boolean dispose) {
if (IsDisposed)
return;
if (disposed) {
// Release any Objects here
// You've allocated the HWND resource so you have to dispose it:
m_HotKeyWnd.DestroyHandle(); // <- Free HWND you've created
}
// Here, you may work with structures only!
// You don't need these assignments, but you can safely do them:
// mayhaps, they'll be useful for you while debugging
m_WindowHandle = IntPtr.Zero;
m_Keys = null;
m_ModKey = null;
// Finally, we've done with disposing the instance
IsDisposed = true;
}
public void Dispose() {
Dispose(true);
// We've done with Dispose: "GC, please, don't bother the disposed instance"
GC.SuppressFinalize(this);
}
// A treacherous enemy I've commented out:
// if you've made a error in Dispose() it'll be resource leak
// or something like AccessViolation. The only good thing is that
// you can easily reproduce (and fix) the problem.
// If you've uncommented ~RegisterPrintKey() this leak/EAV will become
// floating error: it'll appear and disappear on different workstations
// OSs etc: you can't control GC when to run. Floating error is
// much harder to detect.
// Another bad issue with finalizer is that it prevents the instance
// from being in zero generation, see
// http://stackoverflow.com/questions/12991692/why-doesnt-object-with-finalizer-get-collected-even-if-it-is-unrooted
//~RegisterPrintKey() {
// // This code can be called (if called!) at random time
// Dispose(false); // <- That's an enemy!
// }
}
The basic idea is not to touch anything managed in the Dispose(false) variant of your method. Also, there's usually no need to explicitly set anything to null (especially in the Dispose(false) variant, where those objects are probably already garbage collected).
So, you've got the basic pattern right, but you don't need to do anything in Dispose(false) except for the m_HotKeyWnd.DestroyHandle().
To explain a bit more, when the finalizer code is run by the garbage collector, all of the other managed objects referenced by this object (that aren't referenced by others) are probably garbage collected already. Ignore everything that's managed in the finalizer, it probably doesn't even exist anymore. It's also something you can expect in the native callback (ie. your WndProc in this case) - it's very much possible that the managed objects you interact with don't exist anymore, if the callback comes while the object is on the finalizer queue. This is a fairly common cause of application crashes (or at least of unexpected exceptions) in a managed application interacting with native code.
So, Dispose(true) should handle everything you want to clean up, managed and unmanaged (and you're correctly using GC.SuppressFinalize - you've already disposed of the unmanaged resources, so there's no need for GC to put your object on the finalizer queue), Dispose(false) should only ever handle the unmanaged bits.
EDIT: I didn't realize that your m_HotKeyWnd is actually a managed object - it takes care of its unmanaged resources on its own, and you should in no case call its DestroyHandle from the finalizer. In fact, you don't even need the finalizer, its completely redundant (and thus, slightly harmful). Just implement a simple Dispose (instead of the usual finalizer-dispose pattern) that disposes of the m_HotKeyWnd and sets it to null (NullReferenceException is better in this case than AccessViolationException or undefined behaviour you could get when using the object after its been disposed of - unmanaged stuff gets tricky fast), and does nothing else.
In my classes I implement IDisposable as follows:
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int UserID)
{
id = UserID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
}
In VS2012, my Code Analysis says to implement IDisposable correctly, but I'm not sure what I've done wrong here.
The exact text is as follows:
CA1063 Implement IDisposable correctly Provide an overridable implementation of Dispose(bool) on 'User' or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources. stman User.cs 10
For reference: CA1063: Implement IDisposable correctly
I've read through this page, but I'm afraid I don't really understand what needs to be done here.
If anyone can explain in more layman's terms what the problem is and/or how IDisposable should be implemented, that will really help!
This would be the correct implementation, although I don't see anything you need to dispose in the code you posted. You only need to implement IDisposable when:
You have unmanaged resources
You're holding on to references of things that are themselves disposable.
Nothing in the code you posted needs to be disposed.
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int userID)
{
id = userID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
}
// free native resources if there are any.
}
}
First of all, you don't need to "clean up" strings and ints - they will be taken care of automatically by the garbage collector. The only thing that needs to be cleaned up in Dispose are unmanaged resources or managed recources that implement IDisposable.
However, assuming this is just a learning exercise, the recommended way to implement IDisposable is to add a "safety catch" to ensure that any resources aren't disposed of twice:
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
// Indicate that the instance has been disposed.
_disposed = true;
}
}
The following example shows the general best practice to implement IDisposable interface. Reference
Keep in mind that you need a destructor(finalizer) only if you have unmanaged resources in your class. And if you add a destructor you should suppress Finalization in the Dispose, otherwise it will cause your objects resides in memory longer that it should (Note: Read how Finalization works). Below example elaborate all above.
public class DisposeExample
{
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component component = new Component();
// Track whether Dispose has been called.
private bool disposed = false;
// The class constructor.
public MyResource(IntPtr handle)
{
this.handle = handle;
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}
IDisposable exists to provide a means for you to clean up unmanaged resources that won't be cleaned up automatically by the Garbage Collector.
All of the resources that you are "cleaning up" are managed resources, and as such your Dispose method is accomplishing nothing. Your class shouldn't implement IDisposable at all. The Garbage Collector will take care of all of those fields just fine on its own.
You need to use the Disposable Pattern like this:
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose any managed objects
// ...
}
// Now disposed of any unmanaged objects
// ...
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Destructor
~YourClassName()
{
Dispose(false);
}
You have no need to do your User class being IDisposable since the class doesn't acquire any non-managed resources (file, database connection, etc.). Usually, we mark classes as
IDisposable if they have at least one IDisposable field or/and property.
When implementing IDisposable, better put it according Microsoft typical scheme:
public class User: IDisposable {
...
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
// There's no need to set zero empty values to fields
// id = 0;
// name = String.Empty;
// pass = String.Empty;
//TODO: free your true resources here (usually IDisposable fields)
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
Idisposable is implement whenever you want a deterministic (confirmed) garbage collection.
class Users : IDisposable
{
~Users()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
// This method will remove current object from garbage collector's queue
// and stop calling finilize method twice
}
public void Dispose(bool disposer)
{
if (disposer)
{
// dispose the managed objects
}
// dispose the unmanaged objects
}
}
When creating and using the Users class use "using" block to avoid explicitly calling dispose method:
using (Users _user = new Users())
{
// do user related work
}
end of the using block created Users object will be disposed by implicit invoke of dispose method.
I see a lot of examples of the Microsoft Dispose pattern which is really an anti-pattern. As many have pointed out the code in the question does not require IDisposable at all. But if you where going to implement it please don't use the Microsoft pattern. Better answer would be following the suggestions in this article:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
The only other thing that would likely be helpful is suppressing that code analysis warning... https://learn.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs-2017
Callbacks to C# from unmanaged C++ are tricky.
I learned most of the required cruft from this
MSDN article
and this
stackoverflow tip,
and the result works fine in the debugger.
But outside of the debugger it fails with "Object reference not set to an instance of an object".
Here's the (simplified) C# code:
class CSharpCode
{
delegate void CallbackDelegate();
void DoCSharp()
{
CallbackDelegate callbackDelegate = TheCallback;
IntPtr callbackDelegatePointer = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
GCHandle gchCallbackDelegate = GCHandle.Alloc(callbackDelegatePointer);
GC.Collect(); // create max space for unmanaged allocations
CppCliCode.DoCppCli(callbackDelegatePointer);
}
public static void TheCallback()
{
MessageBox.Show("It worked");
}
}
And here's the C++ code:
#pragma managed
public ref class CppCliCode
{
static void DoCppCli(IntPtr^ callbackDelegatePointer)
{
callback theCallback = static_cast<callback>(callbackDelegatePointer->ToPointer());
DoCpp(theCallback);
}
}
#pragma unmanaged
typedef void (__stdcall *callback)();
void DoCpp(callback theCallback)
{
theCallback();
}
The error occurs somewhere between invoking theCallback() and arriving at TheCallback(). The error suggests that some invisible managed object has become null.
If I remove the GC.Collect() the problem goes away. But that just means it will reappear someday as an intermittent mystery when a GC happens to occur at the wrong moment.
The GCHandle protects the delegate from being collected but allows it to be relocated. The MSDN article says "If a delegate is re-located by a garbage collection, it will not affect the underlaying managed callback, so Alloc is used to add a reference to the delegate, allowing relocation of the delegate, but preventing disposal. Using GCHandle instead of pin_ptr reduces fragmentation potential of the managed heap."
What's wrong?
You must allocate the delegate itself, not its IntPtr. Also you must free the GCHandle when you are done with CSharpCode instance.
class CSharpCode : IDisposible
{
delegate void CallbackDelegate();
GCHandle gchCallbackDelegate;
void DoCSharp()
{
CallbackDelegate callbackDelegate = TheCallback;
IntPtr callbackDelegatePointer = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
gchCallbackDelegate = GCHandle.Alloc(callbackDelegate); // !!!!
GC.Collect(); // create max space for unmanaged allocations
CppCliCode.DoCppCli(callbackDelegatePointer);
}
public void Dispose()
{
CleanUp();
}
~CSharpCode()
{
CleanUp();
}
CleanUp()
{
if(gchCallbackDelegate.IsAllocated)
gchCallbackDelegate.Free();
}
}
By the way I hope you have more powerful naming system of yours. Names like DoCSharp, TheCallBack, theCallBack etc. gave me a hard time to understand the question.
I have a C# project in which i use several unmanaged C++ functions.
More so, I also have static IntPtr that I use as parameters for those functions. I know that whenever I use them, I should implement IDisposable in that class and use a destructor to invoke the Dispose method, where I free the used IntPtr, as is said in the MSDN page.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
if (disposing)
{
component.Dispose();
}
CloseHandle(m_InstanceHandle);
m_InstanceHandle = IntPtr.Zero;
disposed = true;
}
}
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
However, when I terminate the application, I'm still left with a hanging process in TaskManager. I believe that it must be related to the used of the MarshalAs instruction in my structures:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SipxAudioCodec
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string CodecName;
public SipxAudioBandwidth Bandwidth;
public int PayloadType;
}
When I create such a structure should I also be careful to free the space it allocs using a destructor?
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SipxAudioCodec
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string CodecName;
public SipxAudioBandwidth Bandwidth;
public int PayloadType;
~SipxAudioCodec()
{
Marshal.FreeGlobal(something...);
}
}
The proper way to handle IntPtr-style handles in p/Invoke interop is:
Define a class SafeMyHandle derived from SafeHandle. It should only override IsInvalid and ReleaseHandle, and do nothing else.
Define another class MyHandle that has methods for the public API for that handle.
MyHandle should have a private member of type SafeMyHandle.
MyHandle should implement IDisposable, and its Dispose method should just call SafeMyHandle.Dispose.
All of the p/Invoke methods should not use IntPtr directly; rather, they should pass and return instances of SafeMyHandle. The one exception is the "freeing function" that is called from SafeMyHandle.ReleaseHandle; it should take an IntPtr.
If you follow these conventions, your handles will be freed even if your AppDomain is rudely torn down.
I have had cases in the past where the application hangs after closing, usually because not all threads were terminated. How do you terminate your app? Maybe threads are the cause?
I am trying to adapt a class to work with just finished that I am not able to solve the problem.
My question is how to identify the handle to close / / CloseHandle (handle).
My problem is that I am not able to adapt the following code.
for (Int32 i = 0; i < temp_items.Count; i++)
{
string conj_itens = temp_itens[i].ToString();
ContarSuporte cs= new ContarSuporte(matriz_bin,strExpr);
_cont = cs.Suporte;
If (_cont>100)
{
list.add(conj_itens);
}
}
public class ContarSuporte: IDisposable
{
private int _cont;
private bool disposed = false;
private IntPtr handle;
public ContarSuporte()
{
}
public ContarSuporte(DataTable matriz_binaria, string strExpr)
{
int c = matriz_binaria.Rows.Count;
this._cont = (int)(matriz_binaria.Compute("COUNT(TID)", strExpr));
}
~ContarSuporte()
{
Dispose(false);
}
public void Dispose()
{
//GC.Collect();
Dispose(true);
GC.SuppressFinalize(this);
// GC.Collect();
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
//this.Dispose();
}
//CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}
public int Suporte
{
get
{
return _cont;
}
set
{
_cont =value;
}
}
You haven't shown any code actually using the handle. Are you really sure you need to implement IDisposable and have a handle in the first place? What unmanaged resource are you trying to use?
Were you perhaps just following a pattern that you saw elsewhere which did use a handle? You should only implement IDisposable when you actually need to - and implementing a finalizer should be very rare these days (as you can use SafeHandle instead of IntPtr for handles).
What handle are you trying to close? I can't see anything that allocates a handle.
Also - in many cases you can use SafeHandle to make this simpler - I can't tell whether this applies in your case, since I can't see what is going on...
the idea is to finish this instruction this._cont = (int)(matriz_binaria.Compute("COUNT(TID)", strExpr)); to each passage, the problem is not to increase the use of the memory I think most is because it is garbage.
my idea was to create a class to avoid the growth of memory. Already placed the _cont variable = 1 and had no impact on memory, and the problem that this raises intrucção memory, and the purpose and effect of each passage was interested in cleaning the garbage memory that is created with this instruction this._cont = (int)(matriz_binaria.Compute("COUNT(TID)", strExpr));**
Thanks