有这样两个C++的接口
EXPORT int GetDoorStatus(int col,char* info);EXPORT unsigned char* GetVuquestData();小弟没做过接C++这种接口的。
网上说用String/byte[]/StringBuilder接的,我都尝试一下,不知道是没写对还是怎么地,总是直接崩溃退出连错都不报希望有大神根据上边俩接口来一段简单明了的Demo

解决方案 »

  1.   

    哦对了,这个char*这个参数的内容是需要带回给我这边C#端的
      

  2.   

            static extern int IsBoxOpen(int box);
            [DllImport("zhilaiBox.dll", CallingConvention = CallingConvention.Cdecl)]        /// <summary>
            /// 测试
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param> 
            private void btnGetDoorStatus_Click(object sender, EventArgs e)
            {
                string txt = "test";
                IntPtr info = Marshal.StringToHGlobalAnsi(txt);
                GetDoorStatus(int.Parse(txtColId.Text), info);
                string strInfo = Marshal.PtrToStringAnsi(info);
                            WriteLog((sender as Button).Text, strInfo.ToString());
            }
    我发现我这么做倒是可以打出来LOG,但是打出来LOG之后就卡死直接崩掉退出了,这是为什么
      

  3.   

    楼上接口引入粘贴错了应该是
            [DllImport("zhilaiBox.dll", CallingConvention = CallingConvention.Cdecl)]
            static extern int GetDoorStatus(int col, IntPtr p);
      

  4.   

    StringBuilder 要先分配大小
      

  5.   

    1. 大多数c/c++ api对于资源管控的原则都是:
    谁使用谁申请谁释放
    所以调用时,不能按照c#的套路,只定义,不申请资源
    具体来说,
    char* info要返回,需要使用stringbuilder来对应
    而stringbuilder需要new时分配空间
    分配大小要根据api的文件来定,和返回对象的大小相关
    比如,使用 StringBuilder test = new StringBuilder();
    那么肯定会引发崩溃,因为c传回的地方只有指针而没有对应的空间
     StringBuilder test = new StringBuilder(40);
    这样就可以了
    2. DllImport的时候,凡涉及char*,就需要说明 CharSet
    c/c++大多数默认是Ansi,而C#默认是Unicode,
    大小不一致,会因为访问越界导致崩溃
      

  6.   

    int GetDoorStatus(int col,ref byte[] info);
    IntPtr GetVuquestData();
      

  7.   

    把我之前做过的一个东西里面有类似的方法贴出来你看看。
    我还记得这种调用必须设置.net framework 3.5 CPU设置为x86才行的,.net版本设置4.0以上或者cpu选择x64、anycpu就会报错误。         [DllImport("SerialExtDll.dll", EntryPoint = "GetNCDataList_AV131", CallingConvention = CallingConvention.Cdecl)]
            private static extern int GetNCDataList_AV131(ref byte sendMsg);        public string GetNCDataList_AV131()
            {
                string result = null;
                try
                {
                    byte[] sendData = new byte[256];
                    GetNCDataList_AV131(ref sendData[0]);
                    int length = 0;
                    for (int i = 0; i < 256; ++i)//去掉指令后面的空字符
                    {
                        if (sendData[i] == 0x00)
                        {
                            length = i;
                            break;
                        }
                    }
                    result = System.Text.Encoding.UTF8.GetString(sendData, 0, length);
                    result = result.ToUpper();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);                
                }
                return result;
            }
    extern "C" SERIALEXTDLL_API int _stdcall GetNCDataList_AV131(char* sendCode)
    {
    byte byteNext[] = { 0x02, 0x30, 0x33, 0x43, 0x31, 0x54, 0x44, 0x35, 0x03 };// 这里是c++写的dll
    char tempCode[256];//
    memset(tempCode,0,sizeof(tempCode)); for(int i =0; i<sizeof(byteNext); ++i)
    {
    sprintf(tempCode,"%c",byteNext[i]);
    strcat(sendCode,tempCode);
    }
    return 0;
    }