Is there a way to remove unused variables from a struct?












1














I have a struct like this



[StructLayout(LayoutKind.Sequential)]
internal struct Context
{
internal uint ContextFlags;

private readonly IntPtr Dr0;
private readonly IntPtr Dr1;
private readonly IntPtr Dr2;
private readonly IntPtr Dr3;
private readonly IntPtr Dr6;
private readonly IntPtr Dr7;

private readonly FloatingSaveArea FloatingSave;

private readonly IntPtr SegGs;
private readonly IntPtr SegFs;
private readonly IntPtr SegEs;
private readonly IntPtr SegDs;

private readonly IntPtr Edi;
private readonly IntPtr Esi;
private readonly IntPtr Ebx;
private readonly IntPtr Edx;
private readonly IntPtr Ecx;
private readonly IntPtr Eax;

private readonly IntPtr Ebp;
internal IntPtr Eip;
private readonly IntPtr SegCs;
private readonly IntPtr EFlags;
private readonly IntPtr Esp;
private readonly IntPtr SegSs;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
private readonly byte ExtendedRegisters;
}


It is filled with data using the following pinvoke method



[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(IntPtr hThread, ref Context lpContext);


I only need access to the variables ContextFlags and Eip



Ideally, I would like to remove all the other variables from the struct that I don't need, however, when I do this, the Eip variable is no longer filled with the correct value.



I have also tried the following



[StructLayout(LayoutKind.Explicit)]
internal struct Context
{
[FieldOffset(0)]
internal uint ContextFlags;

[FieldOffset(184)]
internal IntPtr Eip;
}


The field offset of 184 comes from



uint offsetEip = (uint) Marshal.OffsetOf(typeof(Context), "Eip");


This also doesn't work



Is there a way to achieve this? Maybe through using a class instead of a struct?










share|improve this question






















  • why do you want to do that ?
    – Tigran
    Nov 15 at 21:01






  • 1




    That is not safe; the native code may assume that all fields exist.
    – SLaks
    Nov 15 at 21:01










  • you are probably only saving that 2 digit bytes of disk space by not putting those extra fields in. not really worth the time
    – Steve
    Nov 15 at 21:02










  • I'm just curious to know if its possible
    – user10454073
    Nov 15 at 21:03






  • 1




    @NotQuin: No, it's not possible. If you're concerned about code readability, you can create a wrapper type, that exposes only members of inner struct that you care about.
    – Tigran
    Nov 15 at 21:13


















1














I have a struct like this



[StructLayout(LayoutKind.Sequential)]
internal struct Context
{
internal uint ContextFlags;

private readonly IntPtr Dr0;
private readonly IntPtr Dr1;
private readonly IntPtr Dr2;
private readonly IntPtr Dr3;
private readonly IntPtr Dr6;
private readonly IntPtr Dr7;

private readonly FloatingSaveArea FloatingSave;

private readonly IntPtr SegGs;
private readonly IntPtr SegFs;
private readonly IntPtr SegEs;
private readonly IntPtr SegDs;

private readonly IntPtr Edi;
private readonly IntPtr Esi;
private readonly IntPtr Ebx;
private readonly IntPtr Edx;
private readonly IntPtr Ecx;
private readonly IntPtr Eax;

private readonly IntPtr Ebp;
internal IntPtr Eip;
private readonly IntPtr SegCs;
private readonly IntPtr EFlags;
private readonly IntPtr Esp;
private readonly IntPtr SegSs;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
private readonly byte ExtendedRegisters;
}


It is filled with data using the following pinvoke method



[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(IntPtr hThread, ref Context lpContext);


I only need access to the variables ContextFlags and Eip



Ideally, I would like to remove all the other variables from the struct that I don't need, however, when I do this, the Eip variable is no longer filled with the correct value.



I have also tried the following



[StructLayout(LayoutKind.Explicit)]
internal struct Context
{
[FieldOffset(0)]
internal uint ContextFlags;

[FieldOffset(184)]
internal IntPtr Eip;
}


The field offset of 184 comes from



uint offsetEip = (uint) Marshal.OffsetOf(typeof(Context), "Eip");


This also doesn't work



Is there a way to achieve this? Maybe through using a class instead of a struct?










share|improve this question






















  • why do you want to do that ?
    – Tigran
    Nov 15 at 21:01






  • 1




    That is not safe; the native code may assume that all fields exist.
    – SLaks
    Nov 15 at 21:01










  • you are probably only saving that 2 digit bytes of disk space by not putting those extra fields in. not really worth the time
    – Steve
    Nov 15 at 21:02










  • I'm just curious to know if its possible
    – user10454073
    Nov 15 at 21:03






  • 1




    @NotQuin: No, it's not possible. If you're concerned about code readability, you can create a wrapper type, that exposes only members of inner struct that you care about.
    – Tigran
    Nov 15 at 21:13
















1












1








1







I have a struct like this



[StructLayout(LayoutKind.Sequential)]
internal struct Context
{
internal uint ContextFlags;

private readonly IntPtr Dr0;
private readonly IntPtr Dr1;
private readonly IntPtr Dr2;
private readonly IntPtr Dr3;
private readonly IntPtr Dr6;
private readonly IntPtr Dr7;

private readonly FloatingSaveArea FloatingSave;

private readonly IntPtr SegGs;
private readonly IntPtr SegFs;
private readonly IntPtr SegEs;
private readonly IntPtr SegDs;

private readonly IntPtr Edi;
private readonly IntPtr Esi;
private readonly IntPtr Ebx;
private readonly IntPtr Edx;
private readonly IntPtr Ecx;
private readonly IntPtr Eax;

private readonly IntPtr Ebp;
internal IntPtr Eip;
private readonly IntPtr SegCs;
private readonly IntPtr EFlags;
private readonly IntPtr Esp;
private readonly IntPtr SegSs;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
private readonly byte ExtendedRegisters;
}


It is filled with data using the following pinvoke method



[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(IntPtr hThread, ref Context lpContext);


I only need access to the variables ContextFlags and Eip



Ideally, I would like to remove all the other variables from the struct that I don't need, however, when I do this, the Eip variable is no longer filled with the correct value.



I have also tried the following



[StructLayout(LayoutKind.Explicit)]
internal struct Context
{
[FieldOffset(0)]
internal uint ContextFlags;

[FieldOffset(184)]
internal IntPtr Eip;
}


The field offset of 184 comes from



uint offsetEip = (uint) Marshal.OffsetOf(typeof(Context), "Eip");


This also doesn't work



Is there a way to achieve this? Maybe through using a class instead of a struct?










share|improve this question













I have a struct like this



[StructLayout(LayoutKind.Sequential)]
internal struct Context
{
internal uint ContextFlags;

private readonly IntPtr Dr0;
private readonly IntPtr Dr1;
private readonly IntPtr Dr2;
private readonly IntPtr Dr3;
private readonly IntPtr Dr6;
private readonly IntPtr Dr7;

private readonly FloatingSaveArea FloatingSave;

private readonly IntPtr SegGs;
private readonly IntPtr SegFs;
private readonly IntPtr SegEs;
private readonly IntPtr SegDs;

private readonly IntPtr Edi;
private readonly IntPtr Esi;
private readonly IntPtr Ebx;
private readonly IntPtr Edx;
private readonly IntPtr Ecx;
private readonly IntPtr Eax;

private readonly IntPtr Ebp;
internal IntPtr Eip;
private readonly IntPtr SegCs;
private readonly IntPtr EFlags;
private readonly IntPtr Esp;
private readonly IntPtr SegSs;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
private readonly byte ExtendedRegisters;
}


It is filled with data using the following pinvoke method



[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(IntPtr hThread, ref Context lpContext);


I only need access to the variables ContextFlags and Eip



Ideally, I would like to remove all the other variables from the struct that I don't need, however, when I do this, the Eip variable is no longer filled with the correct value.



I have also tried the following



[StructLayout(LayoutKind.Explicit)]
internal struct Context
{
[FieldOffset(0)]
internal uint ContextFlags;

[FieldOffset(184)]
internal IntPtr Eip;
}


The field offset of 184 comes from



uint offsetEip = (uint) Marshal.OffsetOf(typeof(Context), "Eip");


This also doesn't work



Is there a way to achieve this? Maybe through using a class instead of a struct?







c# struct pinvoke






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 at 21:00







user10454073



















  • why do you want to do that ?
    – Tigran
    Nov 15 at 21:01






  • 1




    That is not safe; the native code may assume that all fields exist.
    – SLaks
    Nov 15 at 21:01










  • you are probably only saving that 2 digit bytes of disk space by not putting those extra fields in. not really worth the time
    – Steve
    Nov 15 at 21:02










  • I'm just curious to know if its possible
    – user10454073
    Nov 15 at 21:03






  • 1




    @NotQuin: No, it's not possible. If you're concerned about code readability, you can create a wrapper type, that exposes only members of inner struct that you care about.
    – Tigran
    Nov 15 at 21:13




















  • why do you want to do that ?
    – Tigran
    Nov 15 at 21:01






  • 1




    That is not safe; the native code may assume that all fields exist.
    – SLaks
    Nov 15 at 21:01










  • you are probably only saving that 2 digit bytes of disk space by not putting those extra fields in. not really worth the time
    – Steve
    Nov 15 at 21:02










  • I'm just curious to know if its possible
    – user10454073
    Nov 15 at 21:03






  • 1




    @NotQuin: No, it's not possible. If you're concerned about code readability, you can create a wrapper type, that exposes only members of inner struct that you care about.
    – Tigran
    Nov 15 at 21:13


















why do you want to do that ?
– Tigran
Nov 15 at 21:01




why do you want to do that ?
– Tigran
Nov 15 at 21:01




1




1




That is not safe; the native code may assume that all fields exist.
– SLaks
Nov 15 at 21:01




That is not safe; the native code may assume that all fields exist.
– SLaks
Nov 15 at 21:01












you are probably only saving that 2 digit bytes of disk space by not putting those extra fields in. not really worth the time
– Steve
Nov 15 at 21:02




you are probably only saving that 2 digit bytes of disk space by not putting those extra fields in. not really worth the time
– Steve
Nov 15 at 21:02












I'm just curious to know if its possible
– user10454073
Nov 15 at 21:03




I'm just curious to know if its possible
– user10454073
Nov 15 at 21:03




1




1




@NotQuin: No, it's not possible. If you're concerned about code readability, you can create a wrapper type, that exposes only members of inner struct that you care about.
– Tigran
Nov 15 at 21:13






@NotQuin: No, it's not possible. If you're concerned about code readability, you can create a wrapper type, that exposes only members of inner struct that you care about.
– Tigran
Nov 15 at 21:13














2 Answers
2






active

oldest

votes


















1














Of course it can work, in the end, it's just an opaque array of bytes, but you must make sure the whole structure size is the same and matches the current hardware/software context, so, just define it like this for an x86 process:



[StructLayout(LayoutKind.Explicit, Size = 716)] // size is 716 for x86
internal struct X86Context
{
[FieldOffset(0)]
internal uint ContextFlags;

[FieldOffset(184)]
internal IntPtr Eip;
}





share|improve this answer





























    0














    The structure is defined in a Windows header file, to correspond to the Windows API function, and it assumes you are passing an address to a allocated/owned memory location of the same size of the complete structure. Since the Windows API function is only getting a pointer, it has to assume you have passed a pointer to the whole structure, although you will only be using two of the members. You can create your own structure of the same size, to expose only the two members that you need.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53327830%2fis-there-a-way-to-remove-unused-variables-from-a-struct%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown
























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      Of course it can work, in the end, it's just an opaque array of bytes, but you must make sure the whole structure size is the same and matches the current hardware/software context, so, just define it like this for an x86 process:



      [StructLayout(LayoutKind.Explicit, Size = 716)] // size is 716 for x86
      internal struct X86Context
      {
      [FieldOffset(0)]
      internal uint ContextFlags;

      [FieldOffset(184)]
      internal IntPtr Eip;
      }





      share|improve this answer


























        1














        Of course it can work, in the end, it's just an opaque array of bytes, but you must make sure the whole structure size is the same and matches the current hardware/software context, so, just define it like this for an x86 process:



        [StructLayout(LayoutKind.Explicit, Size = 716)] // size is 716 for x86
        internal struct X86Context
        {
        [FieldOffset(0)]
        internal uint ContextFlags;

        [FieldOffset(184)]
        internal IntPtr Eip;
        }





        share|improve this answer
























          1












          1








          1






          Of course it can work, in the end, it's just an opaque array of bytes, but you must make sure the whole structure size is the same and matches the current hardware/software context, so, just define it like this for an x86 process:



          [StructLayout(LayoutKind.Explicit, Size = 716)] // size is 716 for x86
          internal struct X86Context
          {
          [FieldOffset(0)]
          internal uint ContextFlags;

          [FieldOffset(184)]
          internal IntPtr Eip;
          }





          share|improve this answer












          Of course it can work, in the end, it's just an opaque array of bytes, but you must make sure the whole structure size is the same and matches the current hardware/software context, so, just define it like this for an x86 process:



          [StructLayout(LayoutKind.Explicit, Size = 716)] // size is 716 for x86
          internal struct X86Context
          {
          [FieldOffset(0)]
          internal uint ContextFlags;

          [FieldOffset(184)]
          internal IntPtr Eip;
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 16 at 16:01









          Simon Mourier

          96.9k12175228




          96.9k12175228

























              0














              The structure is defined in a Windows header file, to correspond to the Windows API function, and it assumes you are passing an address to a allocated/owned memory location of the same size of the complete structure. Since the Windows API function is only getting a pointer, it has to assume you have passed a pointer to the whole structure, although you will only be using two of the members. You can create your own structure of the same size, to expose only the two members that you need.






              share|improve this answer




























                0














                The structure is defined in a Windows header file, to correspond to the Windows API function, and it assumes you are passing an address to a allocated/owned memory location of the same size of the complete structure. Since the Windows API function is only getting a pointer, it has to assume you have passed a pointer to the whole structure, although you will only be using two of the members. You can create your own structure of the same size, to expose only the two members that you need.






                share|improve this answer


























                  0












                  0








                  0






                  The structure is defined in a Windows header file, to correspond to the Windows API function, and it assumes you are passing an address to a allocated/owned memory location of the same size of the complete structure. Since the Windows API function is only getting a pointer, it has to assume you have passed a pointer to the whole structure, although you will only be using two of the members. You can create your own structure of the same size, to expose only the two members that you need.






                  share|improve this answer














                  The structure is defined in a Windows header file, to correspond to the Windows API function, and it assumes you are passing an address to a allocated/owned memory location of the same size of the complete structure. Since the Windows API function is only getting a pointer, it has to assume you have passed a pointer to the whole structure, although you will only be using two of the members. You can create your own structure of the same size, to expose only the two members that you need.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 20 at 18:54

























                  answered Nov 15 at 21:11









                  Brian Clink

                  1118




                  1118






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53327830%2fis-there-a-way-to-remove-unused-variables-from-a-struct%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Wiesbaden

                      Marschland

                      Dieringhausen