views:

1626

answers:

4

How do you write a struct to a place in memory that will be able to be referenced via the ref call and NOT be changed.

I've been passing with ref because I need a pointer to communicate with a dll and the values are getting changed. Not passing by ref throws a "Attempted to read or write protected memory" error.

Thoughts?

+3  A: 

Clone it before passing it by ref. Obviously if you are passing a pointer to your structure to unmanaged code, you have no way of enforcing readonly properties of the memory at that location. Since this is a struct, it could be so simple as this:

If you have this,

private struct DataType
{
    public int X;
    public int Y;
}

private class NativeMethods
{
    [DllImport("MyDll")]
    public static extern void SomeMethod(ref DataType value);
}

Then the call before might be:

DataType data = ...;
NativeMethods.SomeMethod(ref data);

And the call after might be:

DataType data = ...;
DataType temp = data;
NativeMethods.SomeMethod(ref temp);
280Z28
A: 

We really need more information about the functions involved to give you a great answer, but you could try removing the write ability on that area of memory by using VirtualProtectEx.

This assumes that you've allocated some space and stored your information there. You'll want to call VirtualProtectEx with PAGE_READONLY as the new protect constant on that page. For more information check out the MSDN: http://msdn.microsoft.com/en-us/library/aa366899(VS.85).aspx

mrduclaw
While this is something you could try, it's almost certainly a ridiculous solution to this problem.
280Z28
@280Z28 Well, as I said, there's not enough information to provide a great answer. Sure, you could copy all of the data to another buffer, but that's silly expensive and impossible for large data sets. The end goal isn't really defined either. If OP wants to "enforce read-only properties" then my solution is the way to go, as it is provided by the assumed operating system (and is clearly not impossible as you so clearly state).Just because my solution isn't yours doesn't seem like grounds to call it ridiculous, especially when there's unknowns in the question.
mrduclaw
A: 

Do you want to reference some of the Windows DLLs? http://pinvoke.net contains a lot of method definitions.

If you want some more info on a specofic method call, pleaae provide more information.

Zyphrax
A: 

If I understand correctly, you simply need to specify InAttribute, and tell marshaller that structure must be marshaled only once, from c# to native and not backward!

[DllImport("somedll")]
public static extern void SomeMethod(
    [In] ref SomeDataStruct value);
arbiter