 |
|
 |
Hi! - Is there any Source Code available?
I would like to test this Lib on Win7 with x64!
thanks
Daniel
|
|
|
|
 |
|
 |
First than all, I want to thank you by the effort of coding this solution. I found very useful your code to create my own solution in MSIL, I don't want to close the code, so I'm publishing the source here, I only want to make clear that it's my own work:
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) .ver 2: 0: 0: 0
}
.assembly GenericPointers
{
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0: 1: 0: 0
}
.class public abstract auto sealed beforefieldinit PointerBuilder
{
.method public hidebysig static int32 SizeOf<T>() cil managed
{
.maxstack 1
sizeof !!T
ret
}
.method public hidebysig static !!T* AddressOf<T>(!!T var) cil managed
{
.maxstack 1
ldarga.s var
ret
}
.method public hidebysig static !!T* Convert<T>(native int ptr) cil managed
{
.maxstack 1
ldarga.s ptr
call instance void* [mscorlib]System.IntPtr::ToPointer()
ret
}
}
[Use ilasm.exe to compile, this will work on .NET 2.0 or newer]
I know there may be low use for the code, in my persoal point of view I'm using it for an academic project and also I'm seinding a copy to Microsoft with the hope that newer versions of Visual Stuidio allows the use of pointers to generic types in C#, which I were needing, and if it weren't by your code my project could has been stuck for a while.
thanks again.
Ok, about my code for anybody interested, It's an static class, you will access from your project, with three methods: 1) SIzeOf, that's it it returns the size of the given type. 2) AdressOF, it returns a pointer to a value of the generic type, and 3) Convert, it converts a IntPtr (which you can get easy from a void *... so technically from any kind of pointer) to a pointer of the generic type.
This lib targets C# and it has been tested with valuetypes only with excelent results. Use it with your structs and with basic types. I cna't tell how will behave on reference types at the time posting this.
This is barely the code I'm using (with AdressOf included which is not needed):
public static unsafe T? ReadValue<T>(this Stream A)where T : struct
{
int length = PointerBuilder.SizeOf<T>();
byte[] Buffer = new byte[length];
if (A.Read(Buffer, 0, length) == length)
fixed (byte* p = &Buffer[0])
{
T R = *(PointerBuilder.Convert<T>(new IntPtr((void*)p)));
return *PointerBuilder.AddressOf<T>(R);
}
return null;
}
I hope It helps as sample of the use of this lib, please notice that the use of AddressOf in it is just to make a sample, you could just return the value set to R (an avoid that local var). The code is intended as a extension method for stream which aproximates the funtionality of a BinaryReader.
By the way to run extension methods on .NET 2.0, you can include:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method)]
public sealed class ExtensionAttribute : Attribute
{
public ExtensionAttribute() { }
}
}
[Just in case you didn't know :P]
Alfonso J. Ramos (Theraot in Microsoft Connect)
|
|
|
|
 |
|
|
 |
|
 |
Very good job, this is exactly what I was loocking for!
While exploring UnsafeLibrary's abilites:
public Form1()
{
InitializeComponent();
EventHandler clickHandler =
new EventHandler(Form1_Click);
this.Click += clickHandler;
Pointer unsafeLibClickPtr = Unsafe.GetAddressOf(ref clickHandler);
IntPtr marshaledClickPtr = Marshal.GetFunctionPointerForDelegate(clickHandler);
Delegate marshaledClickDlg = Marshal.GetDelegateForFunctionPointer(marshaledClickPtr, typeof(EventHandler));
Delegate unsafeLibClickDlc = Marshal.GetDelegateForFunctionPointer(unsafeLibClickPtr.ToIntPtr(), typeof(EventHandler));
EventHandler derefUnsafeLibEventHandler = unsafeLibClickPtr.Dereference();
if (true == object.ReferenceEquals(clickHandler, derefUnsafeLibEventHandler))
{
System.Diagnostics.Debug.WriteLine("Objects are equal");
}
if (marshaledClickPtr != unsafeLibClickPtr.ToIntPtr())
{
System.Diagnostics.Debug.WriteLine("Pointers are not equal");
}
object o = new object();
GCHandle objectHandle = GCHandle.Alloc(o);
IntPtr objectPtr = GCHandle.ToIntPtr(objectHandle);
Pointer<object> unsafeLibObjectPtr = Unsafe.GetAddressOf(ref o);
object derefUnsafeLibObject = unsafeLibObjectPtr.Dereference();
if (true == object.ReferenceEquals(o, derefUnsafeLibObject))
{
System.Diagnostics.Debug.WriteLine("Objects are equal");
}
if(objectPtr != unsafeLibObjectPtr.ToIntPtr())
{
System.Diagnostics.Debug.WriteLine("Pointers are not equal");
}
GC.KeepAlive(o);
objectHandle.Free();
}
void Form1_Click(object sender, EventArgs e)
{
// Do nothing...
}
I've noticed that the Pointer<>.ToIntPtr()-method returned different values as expected (e.g. here: (objectPtr != unsafeLibObjectPtr.ToIntPtr())). Is it a bug or did I do something wrong?
However, good job
|
|
|
|
 |
|
 |
Thanks! At last someone liked it!
That's because it returns the address to the reference, not the object.
I have no idea how to fix it.
|
|
|
|
 |
|
 |
It is an interesting concept - but I have a hard time of figuring out whether or not this is actually smart or not.
Could you perhaps extend the article / source code with some examples ?
Best regards,
/Michael
|
|
|
|
 |
|
 |
Well, they are mostly useful for Platform Invoke methods which require pointer inputs. Although I guess the Marshaler could pass things by reference, I have a hard time figuring out whether the type will be passed by pointer or not (maybe I'm not experienced). Furthermore, some predefined types need to be passed by pointer, so making a new type is hard or pointless.
Another point (although I don't know if it will really bring a performance benefit):
It might be useful for arrays if you don't want array bound checking to be performed automatically.
|
|
|
|
 |
|
 |
Yes, I know it is primarely for Platform Invoke methods....
But I still could use an example or two - so I can compare it with the traditional way of calling such methods.
/Michael
|
|
|
|
 |
|
 |
Sure.. I'll put some soon.
|
|
|
|
 |
|
 |
I give you credit for writing in MSIL. A good learning experience nonetheless.
Rick
|
|
|
|
 |
|
 |
would you want to do this? The single greatest benefit to .net is that it manages memory allocation and pointers in a safe manner for us. If you want to access pointers directly use C++ and enjoy the Blue Screens of Death that go along with dereferencing the null pointer and walking off the end of your array into OS land.
DancesWithBamboo
|
|
|
|
 |
|
 |
Because many unmanaged functions require pointers, and I think it's a pain to use them otherwise.
|
|
|
|
 |
|
 |
While that's true, there are lots of other ways to work with those functions from managed code that don't also require you to use pointers. Even if you did need to use pointers, you can always use the unsafe keyword and compiler switch.
|
|
|
|
 |
|
 |
The title of this article : Pointer Library for All .NET Languages
In VB.NET , no pointer , no unsafe code
Hi Turion , I like your idea
|
|
|
|
 |
|
 |
It's certainly an interesting concept, but how is it actually useful? What are the real-world problems this is intended to solve?
|
|
|
|
 |
|
 |
Unmanaged API function reference, for one.
|
|
|
|
 |
|
 |
I still don't see how this is really useful. If you're dealing with unmanaged code in .NET you generally don't need to deal with pointers directly and can use the .NET data marshalling capabilities or you do want to use pointers and use the unsafe keyword and compiler switch.
|
|
|
|
 |
|
 |
Uh...
Could you show me how to use VB.NET's /unsafe switch?
Thanks.
The point was that now ANY .NET language can use pointers.
|
|
|
|
 |
|
 |
Ok...that's a valid point. VB doesn't support unsafe code like C# does. It would also help if the article contained a bit more substance by providing some examples of how it could be used and what the real benefits gained are. One of the key concepts behind the .NET Framework is that you don't need to deal with pointers directly anymore (while not entirely true, it is true 99.9% of the time), so I still maintain that this is useful only in limited/specific situations (which should be talked about in the article as well).
|
|
|
|
 |
|
 |
Yeah, the point was not to Always use it - just be able to use it in some cases.
I'll put some examples soon.
|
|
|
|
 |
|
 |
I'm unwilling to test this class because of it's inherit lack of safety, but I do have to wonder what happens when you try to Dispose of items that you've converted. How does Garbage Collection cope with this?
Second point - remove the unnecessary sections from the top of the article.
Deja View - the feeling that you've seen this post before.
|
|
|
|
 |
|
 |
Pete O`Hanlon wrote: How does Garbage Collection cope with this?
My guess is that it doesn't deal with it. The class doesn't appear to implement IDisposable or even a Dispose method.
|
|
|
|
 |
|
 |
It doesn't need to handle anything, because all it creates is a Pointer struct, nothing else. The GetAddressOf returns the address to the item you pass it - it creates nothing else.
Use Reflector to look at the code in C#.
(But of course the code won't recompile in C#...)
|
|
|
|
 |
|
 |
The .NET Framework SDK contains a tool called PeVerify.exe which you can use to verify if .NET assemblies are correct.
The output of compilers should always verify (unless you run into a compiler bug), but if you use ILAsm, you should use the tool to ensure you did not produce invalid IL sequences.
For your assembly, it complains:
[MD]: Error: TypeDef that is not an Interface and not the Object class extends Nil token. [token:0x02000002]
When I compile a static class in C#, it "extends [mscorlib]System.Object", but your class "Unsafe" seems to derive from nothing - this is not allowed in .NET.
|
|
|
|
 |
|
|
 |