简体   繁体   中英

How to convert unmanaged type to managed type in C#?

I'm trying to build a struct for LDAP in C#, but I if I try to convert the InPtr to the struct I defined it throws the following exception: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

        [DllImport("wldap32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_sslinitW",
            SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr ldap_sslinit(string hostName, uint portNumber, int secure);

        //https://docs.microsoft.com/en-us/windows/win32/api/winldap/ns-winldap-ldap
        [StructLayout(LayoutKind.Sequential)]
        public struct LDAP
        {
            [StructLayout(LayoutKind.Sequential)]
            struct ld_sb
            {
                System.UIntPtr sb_sd;
                byte Reserved1;
                System.UIntPtr sb_naddr;
                byte Reserved2;
            }
            string ld_host;
            UInt32 ld_version;
            byte ld_lberoptions;
            UInt32 ld_deref;
            UInt32 ld_timelimit;
            UInt32 ld_sizelimit;
            UInt32 ld_errno;
            string ld_matched;
            string ld_error;
            ulong ld_msgid;
            string Reserved3;
            UInt32 ld_cldaptries;
            UInt32 ld_cldaptimeout;
            UInt32 ld_refhoplimit;
            UInt32 ld_options;
        }

        private const uint LDAP_SSL_PORT = 636;

        static void Main(string[] args)
        {
            IntPtr ld = ldap_sslinit("test", LDAP_SSL_PORT, 1);
            var ldap = Marshal.PtrToStructure(ld, typeof(LDAP)); 
        }

Before this I tried to declare the ldapsslinit method with private static extern LDAP ldap_sslinit(string hostName, uint portNumber, int secure); However, it returns the following error:
'Method's type signature is not PInvoke compatible.'
I think the problem is caused by the LDAP struct I defined, but I don't known which type from unmanged to managed was wrong.

unmanaged managed
UINT_PTR UIntPtr
UCHAR* byte[]
ULONG_PTR UIntPtr
PCHAR string
ULONG UInt32
UCHAR byte

Did I use the wrong mapping in this table?

  1. What specifically are you trying to accomplish. There are managed types in C# for connecting to and using LDAP that don't require native implementations like you are trying to use.

  2. If for some reason you need the native implementation (Note: since you are stuck on step one of a complex handshake I would recommend using a managed implemtation), Instead of the c++ definition of the nested ldap_sslinit struct declare it outside of LDAP

struct ld_sb
{
    System.UIntPtr sb_sd;
    byte Reserved1;
    System.UIntPtr sb_naddr;
    byte Reserved2;
}


public struct LDAP
{
    ld_sb ld_sb;
    string ld_host;
    //...
}```

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM