In C#, how do I invoke a DLL function that returns an unmanaged structure containing a string pointer?

后端 未结 4 1003
天命终不由人
天命终不由人 2020-12-18 11:27

I have been given a DLL (\"InfoLookup.dll\") that internally allocates structures and returns pointers to them from a lookup function. The structures contain string pointer

相关标签:
4条回答
  • 2020-12-18 11:57

    Try the following layout. Code automatically generated using the PInvoke Interop Assistant. Hand coded LookpInfoWrapper()

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct Info {
    
        /// int
        public int id;
    
        /// char*
        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
        public string szName;
    }
    
    public partial class NativeMethods {
    
        /// Return Type: Info*
        ///id: int
        [System.Runtime.InteropServices.DllImportAttribute("InfoLookup.dll", EntryPoint="LookupInfo")]
    public static extern  System.IntPtr LookupInfo(int id) ;
    
        public static LoopInfoWrapper(int id) {
           IntPtr ptr = LookupInfo(id);
           return (Info)(Marshal.PtrToStructure(ptr, typeof(Info));
        }
    
    }
    
    0 讨论(0)
  • Use Marshalling:

    http://www.csharphelp.com/archives/archive63.html

    0 讨论(0)
  • 2020-12-18 12:08

    For an example, see this netapi32.NetShareAdd interop declaration. It includes a SHARE_INFO_502 structure, with a public string shi502_netname member. Many more examples are available at Pinvoke.net.

    0 讨论(0)
  • 2020-12-18 12:17

    You need to implement the structure in C# as well, making sure to use the attributes in the Marshal class properly to ensure that the memory layout matches the unmanaged version.

    So, some variation of this:

    using System.Runtime.InteropServices;
    
    [DllImport("mydll.dll")]
    public static extern Info LookupInfo(int val);
    
    [StructLayout(LayoutKind.Sequential)]
    struct Info
    {
       int id;
       String szName;
    }
    
    private void SomeFunction
    {
       Info info = LookupInfo(0);
       //Note here that the returned struct cannot be null, so check the ID instead
       if (info.id != 0 && !String.IsNullOrEmpty(info.szName))
          DoSomethingWith(info.szName);
    }
    
    0 讨论(0)
提交回复
热议问题