Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Call function from pointer

Call function from pointer

Scheduled Pinned Locked Moved C#
csharpc++htmltutorialquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    joeyespo
    wrote on last edited by
    #1

    Hi, I've searched everywhere! Does anyone here know how to call a function from C# from an IntPtr? I know how to obtain the function pointer: IntPtr ptr = (typeof(SOMECLASS).GetMethod("SomeMethodName").MethodHandle.GetFunctionPointer()) Now I just need a way to call it .. The reason I need this is because in MSHTML, there is an interface called IHTMLElementRender, and the function 'DrawToDC' (useful for capturing HTML documents as an image) takes the argument HDC, but is implemented to take a reference variable of an unrelated structure. Therefore I need to call the function by the pointer, as in C++. Thanks! - Joe Esposito

    M H 2 Replies Last reply
    0
    • J joeyespo

      Hi, I've searched everywhere! Does anyone here know how to call a function from C# from an IntPtr? I know how to obtain the function pointer: IntPtr ptr = (typeof(SOMECLASS).GetMethod("SomeMethodName").MethodHandle.GetFunctionPointer()) Now I just need a way to call it .. The reason I need this is because in MSHTML, there is an interface called IHTMLElementRender, and the function 'DrawToDC' (useful for capturing HTML documents as an image) takes the argument HDC, but is implemented to take a reference variable of an unrelated structure. Therefore I need to call the function by the pointer, as in C++. Thanks! - Joe Esposito

      M Offline
      M Offline
      Mike Dimmick
      wrote on last edited by
      #2

      You've run into one of the limitations of IDL: it was originally for describing structures to be marshalled across processes, but some things we'd like to describe in IDL - handles to GDI and USER objects - are process-relative and have no meaning in another process. So the IDL contains a fake definition. I've browsed Google Groups for _RemotableHandle. The recommended answer is apparently to use ILDASM to generate IL code for the interface, change the declaration to take an IntPtr, then recompile it. Not nice. I'd actually recommend using Managed C++ to wrap the interface as declared in mshtml.h. Stability. What an interesting concept. -- Chris Maunder

      1 Reply Last reply
      0
      • J joeyespo

        Hi, I've searched everywhere! Does anyone here know how to call a function from C# from an IntPtr? I know how to obtain the function pointer: IntPtr ptr = (typeof(SOMECLASS).GetMethod("SomeMethodName").MethodHandle.GetFunctionPointer()) Now I just need a way to call it .. The reason I need this is because in MSHTML, there is an interface called IHTMLElementRender, and the function 'DrawToDC' (useful for capturing HTML documents as an image) takes the argument HDC, but is implemented to take a reference variable of an unrelated structure. Therefore I need to call the function by the pointer, as in C++. Thanks! - Joe Esposito

        H Offline
        H Offline
        Heath Stewart
        wrote on last edited by
        #3

        Instead of wrapping this with an MC++ assembly as the first reply states, just interop the interface yourself. Such it's such a simple interface, it won't be hard:

        [ComImport, Guid("3050f669-98b5-11cf-bb82-00aa00bdce0b"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IHTMLElementRender
        {
        void DrawToDc(IntPtr hdc);
        void SetDocumentPrinter(
        [MarshalAs(UnmanagedType.BStr)] string printerName, IntPtr hdc);
        }

        You could then use Marshal.GetComInterfaceForObject to get a pointer to this interface. You then call Marshal.GetObjectForIUnknown and cast to the interface like so:

        IntPtr ptr = Marshal.GetComInterfaceForObject(element,
        typeof(IHTMLElementRender)); // Interface type from above
        IHTMLElementRender render = (IHTMLElementRender)Marshal.GetObjectForIUnknown(
        ptr);
        render.DrawToDc(hdc);
        // IUknown::Release will be called when 'render' is GC'd, but you must
        // release the IntPtr from GetComInterfaceForObject.
        Marshal.Release(ptr);

        Please note that this is untested but I've used similar code with different interfaces before with success. I hope this helps.

        Microsoft MVP, Visual C# My Articles

        J 1 Reply Last reply
        0
        • H Heath Stewart

          Instead of wrapping this with an MC++ assembly as the first reply states, just interop the interface yourself. Such it's such a simple interface, it won't be hard:

          [ComImport, Guid("3050f669-98b5-11cf-bb82-00aa00bdce0b"),
          InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
          public interface IHTMLElementRender
          {
          void DrawToDc(IntPtr hdc);
          void SetDocumentPrinter(
          [MarshalAs(UnmanagedType.BStr)] string printerName, IntPtr hdc);
          }

          You could then use Marshal.GetComInterfaceForObject to get a pointer to this interface. You then call Marshal.GetObjectForIUnknown and cast to the interface like so:

          IntPtr ptr = Marshal.GetComInterfaceForObject(element,
          typeof(IHTMLElementRender)); // Interface type from above
          IHTMLElementRender render = (IHTMLElementRender)Marshal.GetObjectForIUnknown(
          ptr);
          render.DrawToDc(hdc);
          // IUknown::Release will be called when 'render' is GC'd, but you must
          // release the IntPtr from GetComInterfaceForObject.
          Marshal.Release(ptr);

          Please note that this is untested but I've used similar code with different interfaces before with success. I hope this helps.

          Microsoft MVP, Visual C# My Articles

          J Offline
          J Offline
          joeyespo
          wrote on last edited by
          #4

          Thanks! That did exactly what I needed it to! I did consider using this method, however all of my attempts failed and left me clueless. It seems that this attribute really makes the difference: InterfaceType(ComInterfaceType.InterfaceIsIUnknown) Without it, the program simply crashes when you try to use it. Also, I have been using type-casts where QueryInterface would be required. It also worked in this case: IHTMLElementRender render = (IHTMLElementRender)element; render.DrawToDc(hdc); Thanks again for your reply :) - Joe

          H 1 Reply Last reply
          0
          • J joeyespo

            Thanks! That did exactly what I needed it to! I did consider using this method, however all of my attempts failed and left me clueless. It seems that this attribute really makes the difference: InterfaceType(ComInterfaceType.InterfaceIsIUnknown) Without it, the program simply crashes when you try to use it. Also, I have been using type-casts where QueryInterface would be required. It also worked in this case: IHTMLElementRender render = (IHTMLElementRender)element; render.DrawToDc(hdc); Thanks again for your reply :) - Joe

            H Offline
            H Offline
            Heath Stewart
            wrote on last edited by
            #5

            When you perform a type-cast, the CLR performs a QI (QueryInterface). In some cases, however, the compiler will complain if the object (if it's type is known) doesn't and never could implement that interface. Glad it works for you.

            Microsoft MVP, Visual C# My Articles

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups