外部DLL中有个函数类似以下声明:int fun(const char* p);请问在C#中如何引入这个函数。对于那个参数p比较头痛。使用StringBuilder,IntPtr,byte[],string等都有问题,不能正确调用。返回值代表执行状态,始终不是期望的1。请有经验的大虾指点,谢谢。

解决方案 »

  1.   

    msdn pinvoke看看就知道了,嘿嘿
      

  2.   

    如果我没记错,应该用StringBuilder [in, out],也就是你的DllImport声明要使用这种标记。
    欢迎大家来我的博客作客:http://blog.csdn.net/aafshzj/
    我正在写一系列关于AAF组件框架的文章。该框架能对开发工作提供很多帮助,并极大地提高开发效率。希望大家看一看并提出宝贵建议。
      

  3.   

    或者 ref string,你试一试吧。
      

  4.   

    对于int fun(const char* p);这么简单的函数,
     [DllImport("xxxx.dll")]
            private extern static int fun(string p);
    就可以了,什么都不需要加,有时如果特性加错了,反而出麻烦
      

  5.   

    按道理直接用string就可以,但是既然楼主有问题,所以只好随便试试。可以看看这个:http://windowssdk.msdn.microsoft.com/en-us/library/ms235282(VS.80).aspx当然,也有可能问题根本不在这里,楼主最好能调试看一下,如果dll代码不属于自己那只好询问或检查一下其逻辑什么情况下会返回目前的返回值。
      

  6.   

    char* p
    用什么都可以!不过如果有 不可显示字符的话 最好就用byte[]了 ,没有的话,用 StringBuilder
    //结构定义
    [StructLayout(LayoutKind.Sequential)] 
    public struct GPRS_DATA_RECORD
    {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
    public string m_userid;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string m_recv_date;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
    public byte[] m_data_buf;
    public ushort m_data_len;
    public byte     m_data_type;
    } [StructLayout(LayoutKind.Sequential)] 
    public struct GPRS_USER_INFO
    {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
    public string m_userid;
    public uint     m_sin_addr;     
    public ushort   m_sin_port;     
    public uint     m_local_addr;   
    public ushort   m_local_port; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string   m_logon_date;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string m_update_time;
    public byte m_status;
    }
    /// <summary>
    /// GprsTx 的摘要说明。
    /// </summary>
    public class GprsTx
    {
    private GPRS_DATA_RECORD recdPtr;
    private Thread rxThread = null;
    private Message messTo;
    public System.Threading.AutoResetEvent m_AutoEvent=new AutoResetEvent(false);
    //接收
    public delegate void ReceiveDataEventHandler (GprsEventArgs e);
    //接收事件
    public event ReceiveDataEventHandler ReceiveDataEvent;
    //登录信息
    public delegate void LoingEventHandler(GprsEventArgs e);
    //登录事件
    public event LoingEventHandler LoingEvent;
     

    //定义接口函数
    [DllImport(".\\wcomm_dll.dll")]
    public static extern int start_gprs_server(
    IntPtr hWnd,
    int wMsg,
    int nServerPort,
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder mess);
    [DllImport(".\\wcomm_dll.dll")]
    public static extern int start_net_service(
    IntPtr hWnd,
    int wMsg,
    int nServerPort,
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder mess); [DllImport(".\\wcomm_dll.dll")]
    public static extern int stop_gprs_server(
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder mess);
    [DllImport(".\\wcomm_dll.dll")]
    public static extern int stop_net_service(
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder mess); [DllImport(".\\wcomm_dll.dll")]
    public static extern int do_read_proc(
    ref GPRS_DATA_RECORD recdPtr,
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder mess,
    bool reply); [DllImport(".\\wcomm_dll.dll")]
    public static extern int do_send_user_data(
    [MarshalAs(UnmanagedType.LPStr)]
    string userid,
    [MarshalAs(UnmanagedType.LPArray,SizeConst = 1024)]
    byte[] data,
    int len,
    [MarshalAs(UnmanagedType.LPStr)]
    StringBuilder mess);
    [DllImport(".\\wcomm_dll.dll")]
    public static extern int get_user_info(
    [MarshalAs(UnmanagedType.LPStr)]
    string userid,
    ref GPRS_USER_INFO infoPtr); [DllImport(".\\wcomm_dll.dll")]
    public static extern int get_user_at(
    [MarshalAs(UnmanagedType.LPStr)]
    int index,
    ref GPRS_USER_INFO infoPtr); [DllImport(".\\wcomm_dll.dll")]
    public static extern int SetWorkMode(int nWorkMode);
    [DllImport(".\\wcomm_dll.dll")]
    public static extern uint get_max_user_amount();

    [DllImport(".\\wcomm_dll.dll")]
    public static extern uint get_online_user_amount();
    //
    //定义一些SOCKET API函数
    [DllImport("Ws2_32.dll")]
    private  static  extern  Int32  inet_addr(string  ip);
    [DllImport("Ws2_32.dll")]
    private  static  extern  string inet_ntoa(uint  ip);
    [DllImport("Ws2_32.dll")]
    private  static  extern  uint htonl(uint  ip);
    [DllImport("Ws2_32.dll")]
    private  static  extern  uint ntohl(uint  ip);
    [DllImport("Ws2_32.dll")]
    private  static  extern  ushort htons(ushort  ip);
    [DllImport("Ws2_32.dll")]
    private  static  extern  ushort ntohs(ushort  ip); public const int WM_DTU = 0x400 + 100;
    //接收到的数据包类型(m_data_type):
    internal const int REG_PK = 0x01; //1)0x01 DTU请求注册包
    internal const int RRR_PK = 0x02; //2)0x02 DTU请求注销包
    internal const int RPG_PK = 0x03; //3)0x03 忽略(当DTU尚未注册成功而向DSC发送数据时)
    internal const int RPW_PK = 0x04; //3)0x04 无效的数据包
    internal const int RUD_PK = 0x05; //4)DTU已经接收到DSC发送的用户数据包
    internal const int RUU_PK = 0x09; //5)0x09 DTU向DSC发送的用户数据包
    internal const int RSU_PK = 0x0d; //6)0x0d DTU参数设置成功应答包
    internal const int RFD_PK = 0x0b; //7)0x0b DTU参数查询应答包
    internal const int RDK_PK = 0x06; //8)0x06 请求断开DTU PPP连接成功应答包
    internal const int RSS_PK = 0x07; //9)0x07 请求DTU停止向DSC发送数据成功应答包
    internal const int RKS_PK = 0x08; //10)0x08 请求DTU开始向DSC发送数据成功应答包
    internal const int RQP_PK = 0x0A; //11)0x0A 请求DTU清除缓冲区数据成功应答包
    public void RexMessage(ref Message m)
    {
    this.messTo = m; 
    } public void TiRxThread()
    {
    rxThread.Abort();
    } public void StRxThread()
    {
    rxThread = new Thread(new ThreadStart(this.ReceiveThread));
    rxThread.Start();
    } private void ReceiveThread()
    {
    while(true)
    {
    //if(messTo.Msg == WM_DTU)
    if(m_AutoEvent.WaitOne(1800,true))
    {
    m_AutoEvent.Reset();
    recdPtr = new GPRS_DATA_RECORD();
    StringBuilder mess = new StringBuilder(100);
    do_read_proc(ref recdPtr, mess,true);
    switch (recdPtr.m_data_type)
    {
    case REG_PK: //1)0x01 DTU请求注册包
    GPRS_USER_INFO user_info = new GPRS_USER_INFO();
    GprsEventArgs gpEv;
    if (GprsTx.get_user_info(recdPtr.m_userid, ref user_info) == 0)
    {
    gpEv = new GprsEventArgs();
    gpEv.strMobile = user_info.m_userid;
    gpEv.updateTime = user_info.m_update_time;
    gpEv.byStatus = user_info.m_status;
    if(LoingEvent != null)
    LoingEvent(gpEv);

    }
    break; case RRR_PK: //2)0x02 DTU请求注销包
    break;
    case RPG_PK: //3)0x03 忽略(当DTU尚未注册成功而向DSC发送数据时)
    break;
    case RPW_PK: //3)0x04 无效的数据包
    break; case RUU_PK: //4)0x09 DTU向DSC发送的用户数据包
    gpEv = new GprsEventArgs();
    gpEv.strMobile = recdPtr.m_userid; if(this.Examine(recdPtr.m_data_len, recdPtr.m_data_buf))
    {
    gpEv.byReceive = new byte[recdPtr.m_data_len];
    for(int i = 0 ; i < recdPtr.m_data_len; i ++)
    gpEv.byReceive[i] = recdPtr.m_data_buf[i];
    if (ReceiveDataEvent != null) //新添加代码
    ReceiveDataEvent (gpEv);
    }
    break; case RUD_PK: //5)0x09 DTU向DSC发送的用户数据包 break;
    case RSU_PK: //6)0x0d DTU参数设置成功应答包
    break;
    case RFD_PK: //7)0x0b DTU参数查询应答包
    break;
    case RDK_PK: //8)0x06 请求断开DTU PPP连接成功应答包
    break;
    case RSS_PK: //9)0x07 请求DTU停止向DSC发送数据成功应答包
    break;
    case RKS_PK: //10)0x08 请求DTU开始向DSC发送数据成功应答包
    break;
    case RQP_PK: //11)0x0A 请求DTU清除缓冲区数据成功应答包
    break;
    } }
    }

    } private bool Examine(int len,byte[] data)
    {
    int avgHe = 0;
    for(int i = 2 ; i < (len - 2) ; i++)
    avgHe += data[i];
    int avgHo = data[len - 2];
    avgHo = (avgHo << 8) | (int)data[len -1];
    if(avgHo == avgHe)
    return true;
    else
    return false;

    }
    public GprsTx()
    {
    //
    // TODO: 在此处添加构造函数逻辑
    //
    }
    } public class GprsEventArgs : EventArgs
    {
    public byte[] byReceive; //接收的字节
    public string strReceive; //接收字符串
    public string strMobile; //手机号
    public ushort dataLen; //数据长度
    public string updateTime; //最后一次时间
    public byte byStatus; //在线状态 }
    }
      

  7.   

    我那DLL结构体里声明为 byte[]C++里原形都是 char *