Proper Disposal of Unamanged Struct - c#

Hello this question is a continuation of this question. Provided below is a short version of the code that is loading the data into the structure. The HDF5DotNet library is found here using the 32 bit version with vs2015. My question is, will MyStruct leak memory when SomeCallerClass call HDF5GetSubGroups?
using HDF5DotNet;
namespace CommonClass
{
public class HDF5FileReader
{
public static List<string> HDF5GetSubGroups(string filePath)
{
var returnList = new List<string>();
//... some HDF5 instantiating -- commented out for brevity
var myStruct = new MyStruct[numberOfThingsToRead];
H5A.read(someAttribute, someAttributeType, new H5Array<MyStruct>(myStruct));
string myStructVariableString = IntPtrToString(myStruct[0].intPtr);
returnList.Add(myStructVariableString);
//... closing some HDF5 instantiating -- commented out for brevity
return returnList
}
private string IntPtrToString(IntPtr ipp)
{
string s = Marshal.PtrToStringAnsi(ipp)
//need to free ipp?
return s;
}
}
public struct MyStruct
{
public Int int1;
public IntPtr intPtr;
}
}
namespace CallerClass
{
public class SomeCallerClass()
{
string someFilePath = "Path\To\HDF5File.h5"
var stringList = HDF5FileReader.HDF5GetSubGroups(someFilePath)
//Do Something with StringList -- add to observablecollection
}
public class UnloadingSomeCallerClass()
{
//Clear the observablecollection
}
}

Related

How come C# can handle this obviously idiotic object promotion during run time?

I like the C# language very much. I'm just playing around, and would never use the code below in production code. Obviously the compiler is fooled by the layout of the struct. But how come, that the string on the Super class can still be written and read in run-time? I would have expected some memory access violation. Inspecting the type during run time, it says it is of type Base, see the NoProblem() function execution. No Super class has been instantiated.
How is it able to function like this?
using System;
using System.Runtime.InteropServices;
namespace Fiddle
{
class Program
{
static void Main(string[] args)
{
var b = new Base
{
IntOnBase = 1
};
var overlay = new Overlay();
overlay.Base = b;
var super = overlay.Super;
var intValue = super.IntOnBase;
super.StringOnSuper = "my test string";
var stringValue = super.StringOnSuper;
super.NoProblem();
Expressions.Fiddle();
}
}
[StructLayout(LayoutKind.Explicit)]
public struct Overlay
{
[FieldOffset(0)]
public Super Super;
[FieldOffset(0)]
public Base Base;
}
public class Super : Base
{
public string StringOnSuper { get; set; }
public void NoProblem()
{
Console.WriteLine("You know, I am really a " + this.GetType().Name + " kind of class.");
}
}
public class Base
{
public int IntOnBase { get; set; }
}
}
Well you told the CLR to lay out the memory in advance by using StructLayout (I should caveat this saying this is based on my learning today after experimenting and reading the other answers suggested)
You can tell here that the CLR is not actually instantiating anything. This will throw a NPE. And you can play around with the the constructor on super. It isn't getting invoked, and won't.
Basically you are directly accessing memory, and since string, int etc are all built in types you are safely interacting with them. This should probably require more "intention" by the user, and the other commented questions are all pointing to this requiring an unsafe declaration.
class Program
{
static void Main(string[] args)
{
var b = new Base
{
IntOnBase = 1
};
var overlay = new Overlay();
overlay.Base = b;
var super = overlay.Super;
var intValue = super.IntOnBase;
super.StringOnSuper = 8;
var stringValue = super.StringOnSuper;
System.Diagnostics.Debug.WriteLine(stringValue);
super.NoProblem();
}
}
[StructLayout(LayoutKind.Explicit)]
public struct Overlay
{
[FieldOffset(0)]
public Super Super;
[FieldOffset(0)]
public Base Base;
}
public class NewClass
{
public string cat { get; set; }
}
public class Super : Base
{
private Super imNull;
public Super()
{
// imNull = new Super();
System.Diagnostics.Debug.WriteLine("well i get initialized...");
}
public int StringOnSuper { get; set; }
public void NoProblem()
{
System.Diagnostics.Debug.Write("You know, I am really a " + this.GetType().Name + " kind of class. But my super is " + imNull.ToString() );
}
}
public class Base
{
public int IntOnBase { get; set; }
}

c# - Public Class with index accessor

I want to create a global accessible struct/class (in C#) to access my stock prices from the callback handler.
I know only C and it's easy there
Example in C
struct _Sample
{
int SomeValue;
};
struct _Sample Sample[10];
That's what I have so far in C# after 2 hours of trying.
public static class GlobalVar
{
private static double _StockPrice;
public static double SetStockPrice
{
set
{
_StockPrice = value;
}
}
public static double GetStockPrice
{
get
{
return _StockPrice;
}
}
}
The above example can be used as GlobalVar.SetStockPrice = 10.254; I know I have to use the <List> to make _StockPrice available as an array, but all my attempts to compile a working solution failed.
I would like to access it as GlobalVar[1].SetStockPrice = 1.0; and GlobalVar[1].SetStockPrice = 1.0;
I have to use C# because the SDK I'm using is only available in C#.
You would have to add a StockPrice class and keep an internal dictionary inside of GlobalVar to make this work, but you could use this:
public StockPrice this[int index]
{
get
{
StockPrice stockPrice = null;
if (index > -1)
{
InternalDictionary.TryGetValue(index, out stockPrice);
}
return stockPrice;
}
}
Then you can do GlobalVar[index] to get a certain StockPrice object from that internal dictionary of GlobalVar.
Also note that this will not work on a static class because static indexers are not allowed in C#. You might want to change your class to be a singleton instead of a static.
EDIT: A more complete example (still needs work though) with a singleton implementation:
public class GlobalVars
{
static StockPrices _stockPrices = new StockPrices();
public static StockPrices StockPrices
{
get
{
return _stockPrices ;
}
}
}
public class StockPrices
{
Dictionary<int, StockPrice> InternalDictionary = new Dictionary<int, StockPrice>();
public StockPrice this[int index]
{
get
{
StockPrice stockPrice = null;
if (index > -1)
{
InternalDictionary.TryGetValue(index, out stockPrice);
}
return stockPrice;
}
}
public void Add(StockPrice stockPrice)
{
int index = InternalDictionary.Keys.Max() + 1;
InternalDictionary.Add(index, stockPrice);
}
}
Then you could call your code like this:
GlobalVars.StockPrices[1].DoSomething
The C example you gave, is creating an array with 10 instances of the struct.
The equivalent C# code is this:
struct _Sample
{
public int SomeValue;
public static _Sample[] Sample = new _Sample[10];
};
That is not very C#-ish however. Using C# style I would write something like
struct Sample
{
public int SomeValue { get; set; }
public static Sample[] Values = new Sample[10];
}
You can do something like this to have the same behaviour like in c. Notice that you don't need to make SetField and GetField using { get; set; } you get this behaviour by default (it's a property).
public struct Sample
{
public double StockPrice { get; set; }
}
public static class GlobalVar
{
public static Sample[] Samples = new Sample[10];
}
And to acces use
GlobalVar.Samples[1].StockPrice = 1.0;

Manage a list of Constants

In several projects, we have a list of constant values in the database. These each have a table, name, and a GUID value. For example a Ticket Status table might have 3 values, "Open", "Closed" and "Hold". In our C# code a framework generates a C# file, as follows.
public class TicketStatus {
public static Guid Open = new Guid( "7ae15a71-6514-4559-8ea6-06b9ddc7a59a");
public static Guid Closed = new Guid( "41f81283-57f9-4bda-a03c-f632bd4d1628");
public static Guid Hold = new Guid( "41bcc323-258f-4e58-95be-e995a78d2ca8");
}; // end of TicketStatus
This allows us to write some clean(ish) code that sets ticket status as follows
ticket.strStatus = TicketStatus.Open.ToString();
While this works:
- It produces pretty clean C# code that's easy to ready and maintain
- It's supported by Intellisense
it's still clumsy, in that
- We have to continually convert to string for many operations
- The use of GUIDs seems like overkill.
- We cannot write a "normal" switch statement
// This won't compile
switch( strStatus ) {
case TicketStatus.Open:
case TicketStatus.Closed:
// do some stuff.
break;
}
The code was originally implemented with a bunch of GUIDs, to manage the case when a database would return the values in all upper case.
The question: What's the best way to code these constant values, so that it supports IntelliSense and switch statements?
Thanks Kirk,
Here's the string solution that I'm using.
public static class TicketStatus {
public const string Open = "7ae15a71-6514-4559-8ea6-06b9ddc7a59a";
public const string Closed = "41f81283-57f9-4bda-a03c-f632bd4d1628";
public const string Hold = "41bcc323-258f-4e58-95be-e995a78d2ca8";
}; // end of TicketStatus
string strTemp = TicketStatus.Open;
switch (strTemp) {
case TicketStatus.Open:
strTemp = "Jackpot";
break;
}
Preamble
I do really think, that you should stick to this for as long as you can.
public static class TicketStatus {
public const string Open = "7ae15a71-6514-4559-8ea6-06b9ddc7a59a";
public const string Closed = "41f81283-57f9-4bda-a03c-f632bd4d1628";
public const string Hold = "41bcc323-258f-4e58-95be-e995a78d2ca8";
}; // end of TicketStatus
If you want some magic :)
There is a solution, that nobody has mentioned here. You can use attributes to assign custom values to enumerations. You need to define an attribute and some helper class:
[AttributeUsage(AttributeTargets.Field)]
public class GuidValue : Attribute
{
public Guid Guid
{
get;
private set;
}
public GuidValue(Guid guid)
{
this.Guid = guid;
}
public GuidValue(string stringGuid)
{
this.Guid = new Guid(stringGuid);
}
}
public static class GuidBackedEnums
{
private static Guid GetGuid(Type type, string name)
{
return type.GetField(name).GetCustomAttribute<GuidValue>().Guid;
}
public static Guid GetGuid(Enum enumValue)
{
Type type = enumValue.GetType();
if (!type.IsEnum)
throw new Exception();
return GetGuid(type, enumValue.ToString());
}
public static T CreateFromGuid<T>(Guid guid)
{
Type type = typeof(T);
if (!type.IsEnum)
throw new Exception();
foreach (var value in Enum.GetValues(type))
{
if (guid == GetGuid(type, value.ToString()))
return (T)value;
}
throw new Exception();
}
}
And then you can use it in the following way:
enum TicketStatus
{
[GuidValue("7ae15a71-6514-4559-8ea6-06b9ddc7a59a")]
Open,
[GuidValue("41f81283-57f9-4bda-a03c-f632bd4d1628")]
Closed,
[GuidValue("41bcc323-258f-4e58-95be-e995a78d2ca8")]
Hold
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(GuidBackedEnums.CreateFromGuid<TicketStatus>(new Guid("41f81283-57f9-4bda-a03c-f632bd4d1628")));
Console.WriteLine(GuidBackedEnums.GetGuid(TicketStatus.Hold));
}
}
And, of course, TicketStatus is an ordinary enum. So you can use it in switch statements.
I would use a java-like enum and some reflection. Here's an example C# implementation. It my not work with a switch, but it will quickly identify for you the required object.
using System;
using System.Reflection;
using System.Linq;
public class TicketStatus
{
private string _guid;
private TicketStatus(string guid)
{
_guid = guid;
}
public string GuidValue {get {return _guid; } }
public static readonly TicketStatus Open = new TicketStatus("7ae15a71-6514-4559-8ea6-06b9ddc7a59a");
public static readonly TicketStatus Closed = new TicketStatus("41f81283-57f9-4bda-a03c-f632bd4d1628");
public static readonly TicketStatus Hold = new TicketStatus("41bcc323-258f-4e58-95be-e995a78d2ca8");
//Reads all static readonly fields and selects the one who has the specified GUID
public static TicketStatus Identify(string guid)
{
var ticket = typeof(TicketStatus).GetFields()
.Where(x => (x.IsStatic == true) && (x.IsInitOnly == true) )
.Select(x => x.GetValue(null))
.SingleOrDefault(x => (x as TicketStatus).GuidValue == guid)
as TicketStatus;
return ticket;
}
}
public class Program
{
public static void Main()
{
var guid = "7ae15a71-6514-4559-8ea6-06b9ddc7a59a";
var ticket = TicketStatus.Identify(guid);
if(ticket != null)
{
Console.WriteLine(ticket.GuidValue + " found");
}
else
{
Console.WriteLine("unknown ticket");
}
}
}
try this
public static Guid Open = new Guid("7ae15a71-6514-4559-8ea6-06b9ddc7a59a");
public static Guid Closed = new Guid("41f81283-57f9-4bda-a03c-f632bd4d1628");
public static Guid Hold = new Guid("41bcc323-258f-4e58-95be-e995a78d2ca8");
public enum Status1
{
Open,
Close,
Hold
}
public static Dictionary<Guid, Status1> Dic = new Dictionary<Guid, Status1>()
{
{Open , Status1.Open},
{Closed , Status1.Close},
{Hold , Status1.Hold}
};
and then
var a = TicketStatus.Closed;
var label = TicketStatus.Dic.FirstOrDefault(e => e.Key == a).Value;
switch (label)
{
case TicketStatus.Status1.Close:
}
to keep your code more readable

C# interchangeable properties

I'm trying to create a substitute for kind of property, that accepts multiple types as inputs/outputs.
Here is some pseudo code of one ugly solution:
http://pastebin.com/gbh4SrZX
Basically i have piece of data and i need to be able assign multiple types to it, and react accordingly. I have pieces of data that i operate with, and i need efficient way to manage loading them from file names when needed, while maintaining the same code, if I'm manipulating with data, that's already loaded.
This would be awesome:
SomeDataClass data1 = new SomeDataClass();
SomeDataClass data2 = new SomeDataClass();
data1.Data = "somefile.dat";
data2.Data = data1.Data;
while SomeDataClass.Data is not type of string.
Have you considered using dynamic?
class A {
public dynamic property1 { get; set; }
public dynamic property2 { get; set; }
}
class Program {
static void Main(string[] args) {
A a = new A();
A b = new A();
a.property1 = "hello world!";
b.property2 = a.property1;
Console.WriteLine(b.property2); // writes "hello world!"
}
}
You can do much of that with an implicit conversion operator, i.e.
class SomeDataClass {
public SomeData Data {get;set;}
}
class SomeData {
static SomeData Load(string path) {
return new SomeData(); // TODO
}
public static implicit operator SomeData(string path)
{
return Load(path);
}
}
static class Program {
static void Main()
{
SomeDataClass data1 = new SomeDataClass();
SomeDataClass data2 = new SomeDataClass();
data1.Data = "somefile.dat"; // this is a load
data2.Data = data1.Data; // this is not a load
}
}
However! Frankly, I would consider it more desirable to just make the operation explicit:
class SomeDataClass {
public SomeData Data {get;set;}
}
class SomeData {
public static SomeData Load(string path) {
return new SomeData(); // TODO
}
}
static class Program {
static void Main()
{
SomeDataClass data1 = new SomeDataClass();
SomeDataClass data2 = new SomeDataClass();
data1.Data = SomeData.Load("somefile.dat");
data2.Data = data1.Data;
}
}
Not sure what the problem you're trying to solve with this really is, but it seems to me like you'd be better of with using a byte[], working with a stream of data, loaded either from disk or somewhere else.
Also consider just coding to a common Interface, instead of using dynamic and object.

hide implementation of C# 'using's arguments

I'm trying to abstract marshaling IntPtr to and from structs (actually class, so it's reference type) of data shared with native code.
I have this helper class:
class NativeStruct<StructType> : IDisposable
{
public NativeStruct()
{
_DataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StructType)));
Marshal.PtrToStructure(_DataPtr, _Data);
}
public NativeStruct(IntPtr dataPtr)
{
_DataPtr = dataPtr;
Marshal.PtrToStructure(_DataPtr, _Data);
}
void IDisposable.Dispose()
{
Marshal.StructureToPtr(_Data, _DataPtr, true);
}
public StructType Data { get { return _Data; } }
IntPtr _DataPtr;
public StructType _Data;
}
Is there anyway to make this code implicit:
using (Shared_s data = new Toolbox.NativeStruct<DataStruct>(myIntPtr).Data)
{
data.someMember = someValue;
}
Some way to change this to
EditStruct(DataStruct, myIntPtr)
{
data.someMember = someValue;
}
In C++ I would have used a macro like
#define EditStruct(StructType, IntPtr) using \
(Shared_s data = new Toolbox.NativeStruct<StructType>(IntPtr).data)
The closest thing you can do here is use lambda expressions:
EditStruct<DataStruct>(myIntPtr, data =>
{
data.someMember = someValue;
});
Definition of EditStruct():
void EditStruct<TStruct>(IntPtr dataPtr, Action<TStruct> action)
where TStruct : struct
{
using (var s = new Toolbox.NativeStruct<TStruct>(dataPtr))
{
action(s.Data);
}
}
C# 2.0 version:
EditStruct<DataStruct>(myIntPtr, delegate(DataStruct data)
{
data.someMember = someValue;
});
void EditStruct<TStruct(IntPtr dataPtr, Action<StructType> action) where TStruct : struct
{
using (Toolbox.NativeStruct<StructType> s = new Toolbox.NativeStruct<StructType>(dataPtr))
{
action(s.Data);
}
}

Categories

Resources