Int pointer to unmanaged code

I am new to C # and have a simple (?) Question. From unmanaged code, I get int-pointer:

public foo(ref IntPtr state) { _myState = state; } 

_myState is a member of the IntPtr class. Now I want to exchange states using _myState with unmanaged C ++ code. Everything works if I write this:

 public foo(ref IntPtr state) { _myState = state; ....do some stuff state = 7; } 

In an unmanaged application, I see a new value of 7 . But if I write this:

 public foo(ref IntPtr state) { _myState = state; ...do some stuff _myState = 7; } 

then nothing happens. The initial state value is 0 , and when myState changes to 7 it is not updated in an unmanaged application. How to assign a member variable as _myState the state parameter as a "pointer", so when the state is updated, _myState is also updated? In C ++, this is not a pointer problem ...

Ok, here is the real code:

 [DllExport("QFX_InitializeInterfaceObject", CallingConvention = CallingConvention.StdCall)] public static void QFX_InitializeInterfaceObject( long windowHandle, ref IntPtr processState) { ChartWindowHandle = (IntPtr)windowHandle; OrderCommandProcessState = processState; } 

All I want is that OrderCommandProcessState gets the same link as processState .

+4
source share
1 answer

Firstly, I want to make sure this point is clear: IntPtr is just an integer that is the same size as the native pointer on this machine architecture, it is a 64-bit integer in x64 systems, for example, It doesn’t necessarily has pointer semantics, although, of course, for interop code, the pointer in IntPtrs is often used to safely sort them.

Turning to your specific question, let it ignore the fact that this is IntPtr. Pretend this is just int, because this is basically what it is:

 public void Foo(ref int x) // x is an alias to another variable of type int. { int y = x; // y is a copy of the contents of x y = 7; // The contents of y are no longer a copy of the contents of x } 

Changing y in no way changes x; x is an alias of another variable, and y briefly has a copy of the contents of this variable. This is in no way an alias of the same variable.

How can I make one variable in an alias of another variable, so when the state of one variable is updated, the associated variable is also updated? In C ++, this is not a pointer problem.

Today, in a safe subset, you can only do this with the "ref" and "out" options. The parameter "ref" becomes an alias of this variable. This is the only safe way that you can directly turn one variable into an alias for another.

The CLR also supports links to local languages. We could implement such a function, and actually I prototyped it in C #. In my prototype, you could say:

 public void Foo(ref int x) // x is an alias to another variable of type int. { ref int y = ref x; // y is now an alias to the same variable that x aliases! y = 7; // changing y now changes x, and whatever x // aliases, because those are all the same variable } 

But we have not added this feature in C # and we do not plan to do this any time soon. If you have a convincing use case, I'd love to hear it. (UPDATE: this feature has been added in C # 7.)

(The CLR also allows return type types.) However, the CLR does NOT allow the alias of a variable, and then stores that alias in a field! A field can have a longer life than a bound variable, and CLR developers want to avoid this whole class of errors that attack C and C ++.)

If you know that a variable is tied to a specific place in memory, you can disable the security system and make a pointer to this variable; you then have a completely normal pointer that you can use, just like in C ++. (That is, if the ptr refers to a variable, then *ptr is an alias of that variable.)

 unsafe public void Foo(int* x) // *x is an alias to a variable of type int. { int* y = x; // *y is now an alias to the same variable that *x aliases *y = 7; // changing *y now changes *x, and whatever *x // aliases, because those are all the same variable } 

The CLR does not impose restrictions on the use of pointers; You can store them in the fields if you want. However, if you disable the security system, then you are responsible for ensuring that the garbage collector (or any memory manager that owns this storage - it could not be managed) does not change the location of the variable with an alias for the pointer lifetime. Do not turn off this security system if you really do not know what you are doing; that the security system will protect you.

+12
source

All Articles