• Advertisement

Archived

This topic is now archived and is closed to further replies.

Pointers or similar functionality in C#.

This topic is 5152 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is it possible to do something like pointers in C#? That is, have something like int a; int* b = &a; and then changes in a will reflect in *b; Sorry, I''m still kinda new to C#. --Vic--

Share this post


Link to post
Share on other sites
Advertisement

public unsafe void function()
{
int a;

fixed (int *b = &a)
{
*b = 10;
}
}


project properties: allow unsafe code blocks = true;


the reason fixed is necessary is because a is a managed object. if you want a pointer to a stackalloc object or an unmanaged object (say from a C++ cll or something) the fixed isn't required.

[edited by - Nypyren on January 11, 2004 5:09:28 PM]

Share this post


Link to post
Share on other sites
You can use references in method signatures:

void Foo( ref int bar )
{
bar = 42;
}

int a = 0;
Console.WriteLine( a ); // prints 0

Foo( ref a );
Console.WriteLine( a ); // prints 42



You *can* also use pointers:

unsafe void Bar()
{
int a;
int* b = &a;
*b = 42;
}

Ordinarily, you shouldn''t use pointers.

--
AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
[Project site] [Blog] [RSS] [Browse the source] [IRC channel]

Share this post


Link to post
Share on other sites
quote:
Original post by Nypyren
the reason fixed is necessary is because a is a managed object. if you want a pointer to a stackalloc object or an unmanaged object (say from a C++ cll or something) the fixed isn''t required.

No. a is on the stack. No fixed necessary.

--
AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
[Project site] [Blog] [RSS] [Browse the source] [IRC channel]

Share this post


Link to post
Share on other sites
Also, "ref" parameters need to be initialized (acting both
as input and output parameter), while "out" parameters do not
need to be.




Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
Well, if pointers are not recommended, then I want to do it the *right* way. What I''m doing is creating a GUI. In my GUI, I have an object called a TextBox. This text box has a member

object referenceObject;
int type;

I want to be able to do something like:

TextBox myTextBox = new TextBox();
int a;
myTextBox.SetReferenceObject(a);

And inside the class I want to be able to alter this integer through changes in the textBox (whatever the user types and formatting). I have everything set up except the pointer, and am trying to figure out how to do that.

--Vic--

Share this post


Link to post
Share on other sites
all "class" instances in C# are reference types - each time you assign a class-type variable to a class-tpye instance, it adds a new "reference" to the instance (so that the instance does not delete itself until noone has a reference to him anymore). whenever you assign a class-type variable to null (which happens automatically when the class-type variable goes out of scope), it decrements the reference count of the instance it was pointing at automatically, and it will eventually get cleaned up for you when noone is referenceing it anymore.

This is pretty different from the way you do this kind of thing in C++. You don't use pointer syntax anymore, and you don't have to worry about deleting objects. (there are certain objects built into .Net that you do need to "Dispose" though)


class A
{
public ClassC foo;
//...
}


class B
{
public ClassC foo;
//...
}

class C
{
//...
}


static void Main()
{
A a = new A();
B b = new B();
C c = new C();

a.foo = c;
b.foo = c;

// they are both poiting to the same object. if you then say
a.foo.variable1 = 10;
// then b.foo.variable1 is also 10, because they are referencing the same object.
}



[edited by - Nypyren on January 11, 2004 6:02:03 PM]

[edited by - Nypyren on January 11, 2004 6:05:21 PM]

Share this post


Link to post
Share on other sites
Nypyren, I see that, but the issue is that I''m working with basic types, not objects. That is, classes are all done by reference, but basic types like int, float, string are by value. So my question is how can I work with basic types by reference (notice how in my example I used ints).

--Vic--

Share this post


Link to post
Share on other sites
quote:

Original post by Roof Top Pew Wee
And inside the class I want to be able to alter this integer through changes in the textBox (whatever the user types and formatting). I have everything set up except the pointer, and am trying to figure out how to do that.



Instead of doing that, you can (and should) use an event-driven
model to design your GUI widgets.

e.g. Have TextBox generated a TEXT_CHANGED event which can
be handled by the application. The application will then
update the integer.

That''s how the standard components do things and it works.

Also, think about the consequences of using your GUI your way
in a multi-threaded application. You''ll have to do some
tricky things to make avoid race conditions and other fun stuff.




Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
for value-types, you can "box" them in an "object" class, which turns them into reference-types (for the time being) this won't solve your problem nicely though.


int i;

object o = (object)i;

int b = (int)o; // this breaks the reference, though. assigning to b will not change i's value.


You probably want to follow tangetz's advice and use a Mediator pattern when doing C# GUI:

This is how a Mediator type windows GUI works:


public class MainForm
{
TextBox tb;
int val;

public MainForm()
{
val = 0;

tb = new TextBox();
tb.SetBounds(0,0,100,24);
Controls.Add(tb);
tb.TextChanged += new EventHandler(tb_TextChanged);
// previous line registers the tb_TextChanged function to handle the textbox's TextChanged event.
}

void tb_TextChanged(object sender, EventArgs ea)
{
// we know that tb is the sender in this particular case,
// so we don't have to mess with sender.

try
{
val = Convert.ToInt32(tb.Text); // this throws an exception if the text can't be converted to an integer.
tb.TextColor = Color.Black;
}
catch
{
val = 0;
tb.TextColor = Color.Red; // to show that the input is invalid
}
}
}


This is called a "Mediator" because MainForm is the go-between for the textbox and the integer.

[edited by - Nypyren on January 11, 2004 6:25:45 PM]

Share this post


Link to post
Share on other sites
Hmm. Using events is one solution, but I see one problem. It seems as if you have to specifically create a function - eh, sorry, event - for each individual text box. That is, the example you gave there had a text box affect an integer named val. However, if I were to have a program where there were 10, or 100, or even 1000 text boxes - each with a different variable that they are updating - then I would have to write 1000 different event functions, each with their own variable that they update.

Worse yet, I want to be able to have text boxes change the variable they are updating. So if a text box were to change its variable, I would then have to change the variables. It can be a pain since each variabel will be inside a different event function, thus giving it an alias.

I'm not sure I understand the concequences of doing it with simulated pointers by encasing basic types in classes. I don't know what you mean by avoiding race conditions. However, simply saying tb.SetObject(myInt); seems a lot cleaner than writing a whole function for each individual variable. I prefer to avoid the clutter.

Again, I am still starting out C#, so I may be missing some very important things, so I wouldn't mind some discussion on these topics.

--Vic--

[edited by - Roof Top Pew Wee on January 11, 2004 8:15:31 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Roof Top Pew Wee
And inside the class I want to be able to alter this integer through changes in the textBox (whatever the user types and formatting). I have everything set up except the pointer, and am trying to figure out how to do that.


Don''t do that. System.Windows.Forms/C# isn''t TK.

It wouldn''t even be a good idea in C++.

Share this post


Link to post
Share on other sites
Uhm, the standard gui toolkit used with the TCL language. They are more often referred to combined as "TCL/TK". It works like you described.

Share this post


Link to post
Share on other sites
RTPW: sorta-solution to your idea for 1000+ textboxes.

You can register the same function with each of their events:


EventHandler eh = new EventHandler(handler_function);

for (int i=0; i<1000; i++)
{
textbox[i] = new TextBox();
textbox[i].TextChanged += eh;
textbox[i].Tag = (object)i;
// etc setup stuff for the textboxes.

}


// ... later...


void handler_function(object sender, EventArgs ea)
{
// now, "sender" is whichever textbox sent the event.

// but since we were smart and put an integer tag in each,

// we can index using that.


TextBox tb = (TextBox)sender;

values[(int)tb.Tag] = Convert.ToInt32(tb.Text);

// say that values is an integer array that you created

// elsewhere in the class.

}



[edited by - Nypyren on January 13, 2004 1:39:37 AM]

Share this post


Link to post
Share on other sites
Upon review of the thread, I'm sorta suspicious that you're trying to do something that I've done for a previous project - load binary data from a file and edit it in all possible formats (4 byte = signed/unsigned int32, base 2-36/64, float, little or big endian)

And trust me, what we've all described so far pales in comparison to the complexity of a proper way to do THAT.

You should probably tell us what the underlying concept is so we can stop throwing "well, you can do this instead" ideas at you that don't end up helping.

[edited by - Nypyren on January 13, 2004 1:58:06 AM]

Share this post


Link to post
Share on other sites
Ok, here''s what I''m doing. I am translating and recreating my 2D engine. This 2D engine will contain a GUI as well. In this GUI, I have an object called a TextBox. This TextBox is inherited from my Window class, which is the base of all GUI objects like buttons, list boxes, scroll boxes, etc.

This TextBox has a string text member which it can display by default, but I want to be able to tell this TextBox to also display other variables. In fact, any of the base variables. Bools, ints, strings, floats, doubles, longs, etc.

The philosophy behind my engine is that it should be the easiest game programming engine for 2D. I want to make the coder very efficient, even if this means sacrificing speed.

Now, on to the specifics. I am also in parallel working on a program for my engine called SpriteEditor. This can load up images, create a sprite out of them, and let you do all kinds of possible editing to it, as well as load up other images and create hierarchies with multiple sprites, testing out positions, sizes, and colission.

There will be a properties window which displays info about the sprite, much like in trueSpace, if any of you have ever used that. If you type in a position or scale or whatever, the object selected will change accordingly, but if you grab the object and move it, then the variables change.

My engine works with things I call Handlers. These are big classes that handle all of the little parts of the engine. There is a SpriteHandler which moves, does basic logic, draws, and manages the creation and destruction of sprites. There is also a GUIhandler that does the same thing, only it does it with the GUI instead of sprites.

As I have stated before, to keep things easy for the programmer, almost everything is done behind the scenes. The cursor has the ability to detect which sprites it''s over, and will grab them and move them when you click on sprites.

With all of this in mind, there are a few reasons I want to use pointers:

1. I don''t always know when variables are changed. Sprite position can be changed by velocity and acceleration, colission, attachment to other sprites, the GUI (cursor), changes in the world coordinates, and a few other ways. Therefore, tracking when a sprite changes and calling an event to update the text box is harder.

2. I don''t just want to have text boxes work with sprites. I want coders to simply assign a variable to the text box and have it work like that. No writing events, no keeping track of other stuff. Just assign it and it works.

3. The insides of the engine will be hidden in .dlls, so users won''t be able to survey the changing of variables. They will simply change when they do, and I think that to make things easier, the coder shouldn''t worry about it. If I set the velocity of a sprite, and set some colission instructions, then it will handle itself. This should all be reflected in the text box, and not have to be worried about.

4. I want to later create a VariableHandler where I can give it a variable, value to set it to, and time to set it to. This is very useful for creating things like curved paths, attachments, and other custom behaviors in real time. This type of Handler would work excellently with pointers.

I think this paints an accurate picture of what I am trying to do. But again, my number 1 concern is to keep it easy for the coder.

So, what do you all suggest knowing this? Thanks,

--Vic--

Share this post


Link to post
Share on other sites

  • Advertisement