none
why Intptr no working in .net P/Invoke

    Question

  • i wrote a app to read another app's listview item's ;there is my code 

     [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
            [return: MarshalAsAttribute(UnmanagedType.Bool)]
            public static extern bool WriteProcessMemory(IntPtr hProcess, 
                IntPtr lpBaseAddress,
                IntPtr lpBuffer, uint nSize, 
                [OutAttribute()] out uint lpNumberOfBytesWritten);
    
      IntPtr lviBufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NativeWin32.LVITEM)));
                    Marshal.StructureToPtr(lvi, lviBufferPtr, true);
    
                    NativeWin32.WriteProcessMemory(process, lviBasePtr, lviBufferPtr,
                        (uint)Marshal.SizeOf(typeof(NativeWin32.LVITEM)), out lpNumberOfBytesWritten);
    
    =====================
    above code no working,
    
    then i change the definition of WriteProcessMemory to
    
    //blabla
     public static extern bool WriteProcessMemory(IntPtr hProcess, 
                IntPtr lpBaseAddress,
                ref NativeWin32.LVITEM, uint nSize, 
                [OutAttribute()] out uint lpNumberOfBytesWritten);
      [StructLayoutAttribute(LayoutKind.Sequential)]
            public struct LVITEM
            {
                public uint mask;
                public int iItem;
                public int iSubItem;
                public uint state;
                public uint stateMask;
                public IntPtr pszText;
                public int cchTextMax;
                public int iImage;
                public IntPtr lParam;
            }

    why ?could you help me,thanks


    i like coding

    Thursday, May 10, 2012 6:35 AM

Answers

  • Well, you need to be aware of one major mistake. The prototype for WriteProcessMemory is:

    BOOL WINAPI WriteProcessMemory(
      __in   HANDLE hProcess,
      __in   LPVOID lpBaseAddress,
      __in   LPCVOID lpBuffer,
      __in   SIZE_T nSize,
      __out  SIZE_T *lpNumberOfBytesWritten
    );

    this means you can't have the last two parameters as uint. SIZE_T is a type that changes size depending on platform, so it is 32 bit on 32 bit Windows and 64 bit on 64 bit Windows. So you will need an integer type that resizes depending on platform.

    Anyway, the C# people would probably be better at this since they do this kind of thing all the time. Just because us C++ programmer call these directly, doesn't mean we know how to marshal it to a managed language.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    • Marked as answer by airwolf2026 Friday, May 11, 2012 8:05 AM
    Thursday, May 10, 2012 8:00 AM
  • i find the reason ,in the wrong code ,i use ref intptr lpBuffer,remove the 'ref' now the code work.

    thanks Crescens2k


    i like coding

    • Marked as answer by airwolf2026 Friday, May 11, 2012 8:02 AM
    Friday, May 11, 2012 8:02 AM

All replies

  • Well, you need to be aware of one major mistake. The prototype for WriteProcessMemory is:

    BOOL WINAPI WriteProcessMemory(
      __in   HANDLE hProcess,
      __in   LPVOID lpBaseAddress,
      __in   LPCVOID lpBuffer,
      __in   SIZE_T nSize,
      __out  SIZE_T *lpNumberOfBytesWritten
    );

    this means you can't have the last two parameters as uint. SIZE_T is a type that changes size depending on platform, so it is 32 bit on 32 bit Windows and 64 bit on 64 bit Windows. So you will need an integer type that resizes depending on platform.

    Anyway, the C# people would probably be better at this since they do this kind of thing all the time. Just because us C++ programmer call these directly, doesn't mean we know how to marshal it to a managed language.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    • Marked as answer by airwolf2026 Friday, May 11, 2012 8:05 AM
    Thursday, May 10, 2012 8:00 AM
  • but in my case ,when i change the _in LPCVOID  lpBuffer to  ref LVITEM,the code work fine,why? 

    may be not your last two parameters reason? because mine test platform is win32 x86


    i like coding

    Friday, May 11, 2012 5:39 AM
  • i find the reason ,in the wrong code ,i use ref intptr lpBuffer,remove the 'ref' now the code work.

    thanks Crescens2k


    i like coding

    • Marked as answer by airwolf2026 Friday, May 11, 2012 8:02 AM
    Friday, May 11, 2012 8:02 AM
  • the last two parameters, uint is generate by the tool P/Invoke Interop Assistant version 1.0,it's a mislead?

    i like coding


    Friday, May 11, 2012 8:04 AM
  • Well, it was obvious that the parameter type wasn't the cause of your current problem (the fact that it succeeded one showed this), I was just pointing it out because it was an obvious mistake. If you want this to work in a 64 bit process, the last two parameters can't be 32 bit integers. That is all I was saying.

    Anyway, as I mentioned, try asking this question in one of the C# forums. While people here know C++ and the Win32 API, Platform Invoke to the native world from managed code is something that rarely happens here. So really, why would we learn how to Platform Invoke when we can just call the function directly?

    Since this is purely down to something going wrong with the P/Invoke on the managed side, since it is C# then the C# forums would be the better place to ask.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Do you want Visual Studio 11 Express to be freely installable on Windows 7 and able to write regular C++ applications? Please vote for this.

    Friday, May 11, 2012 8:45 AM
  • Thanks for your tips ,i had change the WriteProcessMemory definition to your tips,

    sorry,i made a misread the forums as c# forums .


    i like coding

    Friday, May 11, 2012 9:30 AM