Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FieldAccessException when trying to access publicized fields. #12

Closed
ameisen opened this issue May 10, 2022 · 7 comments
Closed

FieldAccessException when trying to access publicized fields. #12

ameisen opened this issue May 10, 2022 · 7 comments

Comments

@ameisen
Copy link

ameisen commented May 10, 2022

Whenever a publicized field is accessed, I am getting a FieldAccessException. I have not yet tested it, but I expect that all accesses will likely result in access exceptions.

An example:

	private unsafe void Construct<T>(
		ReadOnlyPinnedSpan<T>.FixedSpan dataIn,
		Vector2I size,
		bool mipmap,
		SurfaceFormat format,
		SurfaceType type,
		bool shared
	) where T : unmanaged {
		glTarget = TextureTarget.Texture2D; // Exception happens here
		format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);
		...
	}

the code in MonoGame looks like this:

namespace Microsoft.Xna.Framework.Graphics
{
    public abstract partial class Texture
    {
        internal int glTexture = -1;
        internal TextureTarget glTarget;
        ...
    }
}

This is what my project file looks like: SpriteMaster.csproj

And this is the properties file it imports: SpriteMasterCommon.props

And all assembly attributes and such are here: Assembly.cs (I should note that removing the security-related attributes changes nothing)

The only unusual thing is that the game (this is a Stardew Valley mod) is loaded through SMAPI, and runs on .NET 5. Mod assemblies are imported dynamically by SMAPI.

@krafs
Copy link
Owner

krafs commented May 10, 2022

Thanks for an exemplary ticket. Couldn't ask for more details :)

The FieldAccessException should have been suppressed by Publicizer setting AllowUnsafeBlocks = true behind the scenes in your project. I see you do that explicitly too.
However, it turns out this only works when the application runs in the Mono runtime (see #13).

Basically: Mono + AllowUnsafeBlocks + accessing publicized member = OK

In your case, Monogame is using .NET5, and using the CoreCLR runtime, which doesn't seem to work.

Unfortunately, I don't know if there is a way to do the same thing in other runtimes than Mono. This means that you probably won't be able to use Publicizer for your use case.

I'll make sure to add a disclaimer about this in the Readme.

@ameisen
Copy link
Author

ameisen commented May 10, 2022

I found another NuGet library that works for my use case: IgnoresAccessChecksToGenerator.

I believe that it largely does the same thing as yours, but also emits IgnoresAccessChecksToAttribute (which the .NET runtime does recognize [SUBJECT_ASSEMBLY_TYPE is System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute], but the C# compiler does not [as it is not exposed, and is largely defined internally and dynamically in the runtime]).

You can see their implementation here.

I'd still prefer to use yours, since it's more flexible. It should be plausible to adopt similar functionality.

@krafs
Copy link
Owner

krafs commented May 12, 2022

I remember seeing that project before. It's remarkable how similar some code segments are to this.
I would imagine the main difference with using Publicizer is the granularity with which you can specify members, instead of blanket-selecting all members in an assembly. The same attribute could most likely be emitted in Publicizer too, yeah.

Unfortunately I don't have the time to dig into this at the moment. I appreciate you preferring Publicizer, but if you need something functional soon, that project is probably better.

@ameisen
Copy link
Author

ameisen commented Jul 31, 2022

Interestingly, I actually end up presently having to use both.

The package that adds the attribute opens up the assembly, but it doesn't actually publicize everything - yours has better support for doing that.

@krafs
Copy link
Owner

krafs commented Aug 28, 2022

Closed by #28.

@krafs krafs closed this as completed Aug 28, 2022
@Hidend
Copy link

Hidend commented Dec 31, 2023

I'm getting FieldAccessException using Publicizer towards a .dll using .NET Framework (v4.0.30319), I'm trying to use:
internal static bool IsSpectating;
And I get System.FieldAccessException, thing is that If I use it with a property that I should actually see, I also get the error:

public static int health;
This last thing is actually not true at 100%, since all these properties come from a class that is internal, so any property that I access from it it will fail:
internal class Main
After Publicizer is applied, I get this:
public class Main
But it does indeed fail, Any ideas?

@krafs
Copy link
Owner

krafs commented Dec 31, 2023

@Hidend We can continue this discussion in a new issue #102

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants