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

空扰寡人 提交于 2019-12-18 05:14:25

问题


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 pointers:

extern "C"
{
   struct Info
   {
      int id;
      char* szName;
   };

   Info* LookupInfo( int id );
}

In C#, how can I declare the structure layout, declare the Interop call, and (assuming a non-null value is returned) utilize the string value? In other words, how do I translate the following into C#?

#include "InfoLookup.h"
void foo()
{
   Info* info = LookupInfo( 0 );
   if( info != 0 && info->szName != 0 )
      DoSomethingWith( info->szName );
   // NOTE: no cleanup here, the DLL is caching the lookup table internally
}

回答1:


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));
    }

}



回答2:


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.




回答3:


Use Marshalling:

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




回答4:


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);
}


来源:https://stackoverflow.com/questions/356851/in-c-how-do-i-invoke-a-dll-function-that-returns-an-unmanaged-structure-contai

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!