none
Trying to fulling understand P-Invoke for performance and best practices. RRS feed

  • Question

  • Hi, I'm looking to see if I'm approaching this subject correctly and how I can speed up performance/production.

    I'm using a program that allows plug-ins. The plug-in is initialized through a Startup function we define in our plug-in dll. This startup function takes in an Interface* that can be used to communicate back to the program. I want to use C# for all my programming but have a thin managed/unmanaged wrapper that allows me to interface with the program. There are 2 parts...

    1) The Program communicates through the plugin from static exported function calls... For this I'm just using global events so in each callback I call a C# event function if the C# plugin registerd to the event.

    Example

    static void GetPlugInInfo(PlugInInfo* info)
    
    {
    
      if (GlobalEvents::GetPlugInInfo != nullptr)
    
      {
    
        ManagedPlugInInfo info;
    
        GlobalEvents::GetPlugInInfo(nullptr, info);
    
        // copy ManagedPlugInInfo -> passed in plug in info by copying each member variable
    
       // is this the fatest way to do this, is there a way I can just do a memcpy if my struct in C# is layed out correctly?
    
    
      }
    
    

    2) The way I need to talk back to the program I am creating a ManagedClass that contains the native ptr. I will support all the function calls for the native class.

    Here are my questions:

    1) Speed is critical for me... What are the best methods I can use when going from C#->CLI that ensures I'm copying my structures as quickly as possible. For instance if my interface function has:

    void ManagedInterface::SetName(String^ name)
    {
       // Marshal String^ -> char*
       // my native call
       m_Interface->SetName(newName);
    }
    
    

    Is there anyway to avoid the native managed allocation for the String^ to char*?

    Alot of my question boils down to how can I use pinning instead of copying in all circumstances? Is that possible?

    2) Are there any tools out there that can auto-generate my CLR code based on just a header?

    3) I believe all my examples are using PInvoke Implicit if that is true than does any Marshalling occur or am I in total control of that and it's only in PInvoke(Explicit) when marshalling is done automatically for you?

    4) Structs... If I layout a struct in C# to be the exact copy of the unmanaged struct I can just use pinning correct? If I have a fixed length string in my struct am I still allowed to use pinning? And does any native copying happen with the String^ conversion to the char* needed?

    5) If a class is exported using class __dllspec(export) can I use explicit PInvoking for that class?

     

    Anyone who takes the time to answer these questions... Thanks so much.

     

     

     


    Keith
    Wednesday, May 18, 2011 3:53 PM

Answers

  • Some data types (e.g. byte, int), called blittable type, have same representation in both managed and native world, CLR will pinning those objects during marshaling; For non-blittable types, CLR use copying.

     

    However, if you do not want CLR to copy large amount of data during p/invoke or COM Interop, you may alloc a block of unmanaged memory in the managed method, and pass the pointer to native function which can operate the memory directly; the AllocHGlobal or AllocCoTaskMem methods of Marshal class may what you need.

     

    See also: Copying and Pinning

     

    I have no idea whether there is such a tool, but PInvoke Interop Assistant tool is one of the best tools I used, you can have a try.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Proposed as answer by eryang Tuesday, June 7, 2011 7:28 AM
    • Marked as answer by eryang Tuesday, June 7, 2011 7:28 AM
    Thursday, June 2, 2011 3:25 AM

All replies

  • PInvoke Interop Assistant can help to translate native method signature to managed definition, is it what you're looking for?


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Proposed as answer by eryang Tuesday, May 31, 2011 7:43 AM
    • Unproposed as answer by eryang Wednesday, June 1, 2011 12:53 AM
    Friday, May 20, 2011 8:16 AM
  • No I think what I was looking for was a more general description like when using PInvoke what things will Pin memory instead of copying memory?

    The second thing I would still like to find is a good tool that can take a header file and create a CLR file for you, but I now know this tool will need to handle nested structs with the header file I'm using.

     

    Keith

     


    Keith
    Tuesday, May 31, 2011 2:17 PM
  • Some data types (e.g. byte, int), called blittable type, have same representation in both managed and native world, CLR will pinning those objects during marshaling; For non-blittable types, CLR use copying.

     

    However, if you do not want CLR to copy large amount of data during p/invoke or COM Interop, you may alloc a block of unmanaged memory in the managed method, and pass the pointer to native function which can operate the memory directly; the AllocHGlobal or AllocCoTaskMem methods of Marshal class may what you need.

     

    See also: Copying and Pinning

     

    I have no idea whether there is such a tool, but PInvoke Interop Assistant tool is one of the best tools I used, you can have a try.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Proposed as answer by eryang Tuesday, June 7, 2011 7:28 AM
    • Marked as answer by eryang Tuesday, June 7, 2011 7:28 AM
    Thursday, June 2, 2011 3:25 AM