访问冲突异常,当我调用dll方法时

时间:2016-09-17 11:53:34

标签: c#

我如何从dll调用函数?我有AccessViolationExeception

我在C上签名:

int WINAPI LogonNowait(Context* comm, 
              char*   host, 
              char*   username,
              char*   password,
              char*   shell_cmd,
              char*   logon_error_msg,
              int     buflen,
              SOCKET* sIO,
              SOCKET* sErr
              )

[DllImport(@"C:\\MyDLL.dll")]
        public static extern int WaitForLogon(ref Context ctx, ref string errmsg, int bLen, ref int sIO, ref int sErr);

 [StructLayout(LayoutKind.Sequential)]
    public struct CommContext
    {
        public uint inited;

        public uint rbufsize;
        public uint rbuf;
        public uint r_in_container;
        public uint left_in_container;
        public uint next_in_container;


        public uint wbufsize;
        public uint wbuf;
        public uint w_in_container;
        public uint first_free;
        public uint empty_container;

        public uint socket;
        public uint hdrtype;
        public uint last_error;
        public uint socket2;
        public string RX_context;
        public int port;
        public uint async_header;
        public string my_host_addr;

        public override string ToString()
        {
            return port.ToString();
        }
    }

附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。 我怎样才能正确地从C#调用这个方法?

1 个答案:

答案 0 :(得分:-1)

我会做这样的事情。不确定它是否完全正确,但是接近。我更新了原始帖子,以摆脱设置套接字时发生的错误。您必须在运行代码之前初始化CommContext。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
            //int WINAPI LogonNowait(Context* comm, 
            //  char*   host, 
            //  char*   username,
            //  char*   password,
            //  char*   shell_cmd,
            //  char*   logon_error_msg,
            //  int     buflen,
            //  SOCKET* sIO,
            //  SOCKET* sErr
            //  )
        [DllImport(@"C:\\MyDLL.dll",CallingConvention = CallingConvention.Cdecl)]
        public static extern int WaitForLogon(IntPtr ctx, IntPtr host, IntPtr username, IntPtr password, IntPtr shell_cmd,  IntPtr errmsg, int bLen, IntPtr sIO, IntPtr sErr);

        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern Int32 WSAStartup(Int16 wVersionRequested, out WSAData wsaData);

        [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern IntPtr socket(ADDRESS_FAMILIES_INT af, SOCKET_TYPE_INT socket_type, PROTOCOL_INT protocol);

        internal enum ADDRESS_FAMILIES_INT : int
        {
            /// <summary>
            /// Unspecified [value = 0].
            /// </summary>
            AF_UNSPEC = 0,
            /// <summary>
            /// Local to host (pipes, portals) [value = 1].
            /// </summary>
            AF_UNIX = 1,
            /// <summary>
            /// Internetwork: UDP, TCP, etc [value = 2].
            /// </summary>
            AF_INET = 2,
            /// <summary>
            /// Arpanet imp addresses [value = 3].
            /// </summary>
            AF_IMPLINK = 3,
            /// <summary>
            /// Pup protocols: e.g. BSP [value = 4].
            /// </summary>
            AF_PUP = 4,
            /// <summary>
            /// Mit CHAOS protocols [value = 5].
            /// </summary>
            AF_CHAOS = 5,
            /// <summary>
            /// XEROX NS protocols [value = 6].
            /// </summary>
            AF_NS = 6,
            /// <summary>
            /// IPX protocols: IPX, SPX, etc [value = 6].
            /// </summary>
            AF_IPX = 6,
            /// <summary>
            /// ISO protocols [value = 7].
            /// </summary>
            AF_ISO = 7,
            /// <summary>
            /// OSI is ISO [value = 7].
            /// </summary>
            AF_OSI = 7,
            /// <summary>
            /// european computer manufacturers [value = 8].
            /// </summary>
            AF_ECMA = 8,
            /// <summary>
            /// datakit protocols [value = 9].
            /// </summary>
            AF_DATAKIT = 9,
            /// <summary>
            /// CCITT protocols, X.25 etc [value = 10].
            /// </summary>
            AF_CCITT = 10,
            /// <summary>
            /// IBM SNA [value = 11].
            /// </summary>
            AF_SNA = 11,
            /// <summary>
            /// DECnet [value = 12].
            /// </summary>
            AF_DECnet = 12,
            /// <summary>
            /// Direct data link interface [value = 13].
            /// </summary>
            AF_DLI = 13,
            /// <summary>
            /// LAT [value = 14].
            /// </summary>
            AF_LAT = 14,
            /// <summary>
            /// NSC Hyperchannel [value = 15].
            /// </summary>
            AF_HYLINK = 15,
            /// <summary>
            /// AppleTalk [value = 16].
            /// </summary>
            AF_APPLETALK = 16,
            /// <summary>
            /// NetBios-style addresses [value = 17].
            /// </summary>
            AF_NETBIOS = 17,
            /// <summary>
            /// VoiceView [value = 18].
            /// </summary>
            AF_VOICEVIEW = 18,
            /// <summary>
            /// Protocols from Firefox [value = 19].
            /// </summary>
            AF_FIREFOX = 19,
            /// <summary>
            /// Somebody is using this! [value = 20].
            /// </summary>
            AF_UNKNOWN1 = 20,
            /// <summary>
            /// Banyan [value = 21].
            /// </summary>
            AF_BAN = 21,
            /// <summary>
            /// Native ATM Services [value = 22].
            /// </summary>
            AF_ATM = 22,
            /// <summary>
            /// Internetwork Version 6 [value = 23].
            /// </summary>
            AF_INET6 = 23,
            /// <summary>
            /// Microsoft Wolfpack [value = 24].
            /// </summary>
            AF_CLUSTER = 24,
            /// <summary>
            /// IEEE 1284.4 WG AF [value = 25].
            /// </summary>
            AF_12844 = 25,
            /// <summary>
            /// IrDA [value = 26].
            /// </summary>
            AF_IRDA = 26,
            /// <summary>
            /// Network Designers OSI &amp; gateway enabled protocols [value = 28].
            /// </summary>
            AF_NETDES = 28,
            /// <summary>
            /// [value = 29].
            /// </summary>
            AF_TCNPROCESS = 29,
            /// <summary>
            /// [value = 30].
            /// </summary>
            AF_TCNMESSAGE = 30,
            /// <summary>
            /// [value = 31].
            /// </summary>
            AF_ICLFXBM = 31
        }

        internal enum SOCKET_TYPE_INT : int
        {
            /// <summary>
            /// stream socket 
            /// </summary>
            SOCK_STREAM = 1,

            /// <summary>
            /// datagram socket 
            /// </summary>
            SOCK_DGRAM = 2,

            /// <summary>
            /// raw-protocol interface 
            /// </summary>
            SOCK_RAW = 3,

            /// <summary>
            /// reliably-delivered message 
            /// </summary>
            SOCK_RDM = 4,

            /// <summary>
            /// sequenced packet stream 
            /// </summary>
            SOCK_SEQPACKET = 5
        }
        internal enum PROTOCOL_INT : int
        {
            //dummy for IP  
            IPPROTO_IP = 0,
            //control message protocol  
            IPPROTO_ICMP = 1,
            //internet group management protocol  
            IPPROTO_IGMP = 2,
            //gateway^2 (deprecated)  
            IPPROTO_GGP = 3,
            //tcp  
            IPPROTO_TCP = 6,
            //pup  
            IPPROTO_PUP = 12,
            //user datagram protocol  
            IPPROTO_UDP = 17,
            //xns idp  
            IPPROTO_IDP = 22,
            //IPv6  
            IPPROTO_IPV6 = 41,
            //UNOFFICIAL net disk proto  
            IPPROTO_ND = 77,

            IPPROTO_ICLFXBM = 78,
            //raw IP packet  
            IPPROTO_RAW = 255,

            IPPROTO_MAX = 256
        }

        // For 32-bit execution
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct WSAData
        {
            public Int16 version;
            public Int16 highVersion;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
            public String description;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
            public String systemStatus;

            public Int16 maxSockets;
            public Int16 maxUdpDg;
            public IntPtr vendorInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CommContext
        {
            public uint inited;

            public uint rbufsize;
            public uint rbuf;
            public uint r_in_container;
            public uint left_in_container;
            public uint next_in_container;


            public uint wbufsize;
            public uint wbuf;
            public uint w_in_container;
            public uint first_free;
            public uint empty_container;

            public uint socket;
            public uint hdrtype;
            public uint last_error;
            public uint socket2;
            public string RX_context;
            public int port;
            public uint async_header;
            public string my_host_addr;

            public override string ToString()
            {
                return port.ToString();
            }
        }

        static void Main(string[] args)
        {
            CommContext cmt = new CommContext();
            IntPtr cmtPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cmt));
            Marshal.StructureToPtr(cmt, cmtPtr, true);

            string host = "LocalHost";
            byte[] hostBytes = Encoding.UTF8.GetBytes(host + "\0");
            IntPtr hostPtr = Marshal.AllocHGlobal(hostBytes.Length);
            Marshal.Copy(hostBytes, 0, hostPtr, hostBytes.Length);

            string username = "username";
            byte[] usernameBytes = Encoding.UTF8.GetBytes(username + "\0");
            IntPtr usernamePtr = Marshal.AllocHGlobal(usernameBytes.Length);
            Marshal.Copy(usernameBytes, 0, usernamePtr, usernameBytes.Length);

            string password = "password";
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password + "\0");
            IntPtr passwordPtr = Marshal.AllocHGlobal(passwordBytes.Length);
            Marshal.Copy(passwordBytes, 0, passwordPtr, passwordBytes.Length);

            string shell_cmd = "shell_cmd";
            byte[] shell_cmdBytes = Encoding.UTF8.GetBytes(shell_cmd + "\0");
            IntPtr shell_cmdPtr = Marshal.AllocHGlobal(shell_cmdBytes.Length);
            Marshal.Copy(shell_cmdBytes, 0, shell_cmdPtr, shell_cmdBytes.Length);

            const int BUF_LEN = 256;
            IntPtr errmsgPtr = new IntPtr(BUF_LEN);
            int bLen = BUF_LEN;

            WSAData data = new WSAData();
            WSAStartup(0x201, out data);

            IntPtr sio = socket(ADDRESS_FAMILIES_INT.AF_INET, SOCKET_TYPE_INT.SOCK_STREAM, PROTOCOL_INT.IPPROTO_TCP);

            IntPtr sErr = socket(ADDRESS_FAMILIES_INT.AF_INET, SOCKET_TYPE_INT.SOCK_STREAM, PROTOCOL_INT.IPPROTO_TCP);

            int results = WaitForLogon(cmtPtr, hostPtr, usernamePtr, passwordPtr, shell_cmdPtr, errmsgPtr, bLen, sio, sErr);

            string error = Marshal.PtrToStringAuto(errmsgPtr);
        }
    }
}