public struct PTask
    {
        public IntPtr command; // 命令,4位        
        public IntPtr taskType; // 任务类型,4位
        public IntPtr taskID; // 任务ID,32位
        public IntPtr srcTaskID; // 最初任务ID,32位
        public IntPtr srcRequesterID; // 最初请求方ID,12位
        public IntPtr senderID; // 发送方ID,12位
        public IntPtr receiverID; // 接收方ID,每个12位
        public IntPtr priority; // 优先级,1位
        public IntPtr isACK; // 是否要求回执,1位
        public IntPtr invalidation; // 失效时间,13位
        public IntPtr sentTime; // 数据发送时间,14位
        public IntPtr taskName; // 任务名称,32位
        public IntPtr taskBody; // 任务体
    }
        [DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr sendTask(ref PTask task, IntPtr ip, IntPtr port);
        [DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr receiveTask(ref PTask task, IntPtr ip, IntPtr port, ref bool other);
        [DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern string errorCodeTrans(IntPtr name);
        [DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern string free_char(IntPtr name); public string GetPCI(string sCode)
        {
            string result = string.Empty;
            PTask oTask;
            PTask oTask2;
            IntPtr iTask = IntPtr.Zero;
            IntPtr iRet = IntPtr.Zero;
            string sError = string.Empty;
            string sRet = string.Empty;
            string sTask = string.Empty;
            bool bTmp;
            int i = 0;
            IntPtr sIp = IntPtr.Zero;
            IntPtr sPort = IntPtr.Zero;
            try
            {
                result = "";
                oTask = new PTask();
                oTask.senderID = Marshal.StringToHGlobalAnsi(PopSendId);
                oTask.receiverID = Marshal.StringToHGlobalAnsi(PopReceiveId);
                oTask.taskName = Marshal.StringToHGlobalAnsi("query");
                oTask.taskBody = Marshal.StringToHGlobalAnsi(GetBody(sCode));
                //oTask.taskBody = Marshal.StringToCoTaskMemAuto(GetBody(sCode));  
                sIp = Marshal.StringToHGlobalAnsi(PopIp);
                sPort = Marshal.StringToHGlobalAnsi(PopPort);                
                iTask = sendTask(ref oTask, sIp, sPort);
                sTask = Marshal.PtrToStringAnsi(iTask);
                if (sTask.Length != 32)
                {
                    sError = errorCodeTrans(iTask);
                    free_char(iTask);
                }
                bTmp = true;
                oTask2 = new PTask();
                oTask2.senderID = Marshal.StringToHGlobalAnsi(PopSendId);
                oTask2.receiverID = Marshal.StringToHGlobalAnsi(PopReceiveId);  
                oTask2.taskName = Marshal.StringToHGlobalAnsi("query");
                oTask2.taskBody = Marshal.StringToHGlobalAnsi("");
                oTask2.srcTaskID = Marshal.StringToHGlobalAnsi(sTask.Substring(0, sTask.Length - 1));
                //free_char(iTask);
                Thread.Sleep(3000);
                for (i = 1; i <= 20; i++)
                {
                    iRet = receiveTask(ref oTask2, sIp, sPort, ref bTmp);
                    sRet = Marshal.PtrToStringAnsi(iRet);
                    if (sRet != null)
                    {
                        if (sRet.Length == 4)
                        {
                            sError = errorCodeTrans(iTask);
                            free_char(iRet);
                            //Units.uUserThread.error(sError);
                        }
                        else
                        {
                            result = sRet;
                            free_char(iRet);
                        }
                        break;
                    }
                }
            }
            catch (Exception Ex)
            {
                throw new Exception(Ex.Message);
            }
            return result;
        }  TTask=record
    command:pchar; // 命令,4位
    taskType:pchar; // 任务类型,4位
    taskID:pchar; // 任务ID,32位
    srcTaskID:pchar; // 最初任务ID,32位
    srcRequesterID:pchar; // 最初请求方ID,12位
    senderID:pchar ; // 发送方ID,12位
    receiverID:pchar; // 接收方ID,每个12位
    priority:pchar; // 优先级,1位
    isACK:pchar; // 是否要求回执,1位
    invalidation:pchar; // 失效时间,13位
    sentTime:pchar; // 数据发送时间,14位
    taskName:pchar; // 任务名称,32位
    taskBody:pchar; // 任务体
  end;
 function sendTask(task:PTask;ip:pchar;port:pchar):pchar;cdecl;external 'PCI2.DLL';
  function receiveTask(task:PTask;ip:pchar;port:pchar;other:PBool):pchar;cdecl;external 'PCI2.DLL';
  function errorCodeTrans(name:pchar):pchar;cdecl;external 'PCI2.DLL';
  function free_char(name:pchar):pchar;cdecl;external 'PCI2.DLL';
function TPopThread.GetPCI(sCode: String):String;
var
  oTask,oTask2:TTask;
  sTask,sError,sRet:pchar;
  bTmp:boolean;
  i:integer;
  sIp,sPort:pchar;
begin
  try
    try
      Result:='';
      ZeroMemory(@oTask,SizeOf(TTask));
      oTask.senderID:=pchar(Global.GetConfig('PopSendId'));
      oTask.receiverID:=pchar(Global.GetConfig('PopReceiveId'));
      oTask.taskName:='query';
      oTask.taskBody:=pchar(getBody(sCode));
      sIp:=pchar(Global.GetConfig('PopIp'));
      sPort:=pchar(Global.GetConfig('PopPort'));
      sTask:=sendTask(@oTask,sIP,sPort);
      try
        if length(sTask)<>32 then
          begin
             sError:=errorCodeTrans(sTask);
             free_char(sTask);
             error(sError);
          end;
      finally
        //free_char(sTask);
      end;
      bTmp:=true;
      ZeroMemory(@oTask2,SizeOf(TTask));
      oTask2.senderID:=pchar(Global.GetConfig('PopSendId'));
      oTask2.receiverID:=pchar(Global.GetConfig('PopReceiveId'));
      oTask2.taskName:='query';
      oTask2.taskBody:='';
      oTask2.srcTaskID:=PChar(Copy(sTask,1,Length(sTask)));
      free_char(sTask);
      Sleep(StrToInt(Global.GetConfig('PopSleepTime')));
      for i:=1 to 20 do
        begin
           sRet:=ReceiveTask(@oTask2,pchar(sIp),pchar(sPort),@bTmp);
           if sRet<>nil then
             try
                if length(sRet)=4 then
                  begin
                    sError:=errorCodeTrans(sTask);
                    free_char(sRet);
                    error(sError);
                  end
                else
                  begin
                    Result:=sRet;
                    free_char(sRet);
                  end;
                break;
             finally
               //free_char(sRet);
             end;
           Sleep(StrToInt(Global.GetConfig('PopSleepTime')));
        end;
    except
      on Ex:Exception do
        begin
          RaiseError(Ex,'GetPCI');
        end;
    end;
  finally  end;
end;
2个都是调用的c++动态库 ,delphi运行正常 , c#返回的是请求报文格式不正确 , 求大佬帮帮忙

解决方案 »

  1.   

    C++接口是什么样的 是不是C++和C#类型没对应好
      

  2.   

    2个都是调用的c++动态库 ,delphi运行正常 , c#返回的是请求报文格式不正确   动态库返回错误
      

  3.   

    没有给我c++原型,给了delphi的demo   delphi我运行了没有问题,我转化的c#就有问题,我是按照delphi定义的类型去定义的c#的。按道理,c++接收的肯定是指针地址。
      

  4.   

    [StructLayout(LayoutKind.Sequential)]
    public struct PTask
      

  5.   

    这个我加着的  贴代码的时候没有贴上来 我完整的是 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]  
      

  6.   

    你应该把整个结构体放在unmanaged memory中:
            [DllImport("PCI2.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr sendTask(IntPtr task, IntPtr ip, IntPtr port);
      

  7.   

    大哥   意思是我需要在传结构体的时候   使用intPtr传输是吗  。那么我的代码是不是应该这么写:
    sPort = Marshal.StringToHGlobalAnsi(PopPort);
                    IntPtr intpt = Marshal.AllocHGlobal(Marshal.SizeOf(oTask));   //对intpt分配内存
                    iTask = sendTask(intpt, sIp, sPort);
                    sTask = Marshal.PtrToStringAnsi(iTask);
    大哥 你有企鹅什么的吗  
      

  8.   

    那个结构体的定义,在C#和Delphi中,内存布局要完全一致,对齐方式要一致,就是把结构中所有的成员依次排列到一起,就是一个byte数组,像你的定义里面,那些半个字节、1比特的成员能组合成整字节的就组合成整字节的,或者写一个方法从字节数组的某个偏移量取出多少来转换,那个taskbody,也要能展开成字节数组放进来。就是整个结构体,要能当做一个字节数组用
      

  9.   

    主要是我没有原型,只能通过delphi代码去转成c#代码
      

  10.   

    Quote: 引用 15 楼 小_菜1 的回复:

    结构定义里的每个成员的位数,是bit还是字符数?
      

  11.   

    那个结构成员全是指针,不会有结构对齐尺寸导致的问题
    如果还不行,你可以考虑用一下unsafe
        public unsafe struct PTask
        {
            public byte *command;
            public byte *taskType;
    // ...
        }
      

  12.   

    没定义位数,因为没有原型,给的delphi里面没有也就没定义
      

  13.   

    我觉得你还是找一下C++的接口定义  如果是用别的公司的SDK  那么会有说明 如果是自己公司的 源码都会有
      

  14.   

    最好还是找一找 你现在用delphi代码 改成C#  很多数据格式都得猜  得一个一个试验 老费劲了 而且像这种库类C++DLL 应该是会有相应的头文件的 里面有接口定义
      

  15.   

    这种就不纠结了,把delphi的写成一个dll,让delphi的中间代理访问就好。你跟我不对付,我找个能跟你对付的人去做