最近做硬件接口的调用,对方是C++,我用的C#调用,前几天整的大部分方法能调用了,但是现在卡在c++返回结构了。C++结构声明 ,人家之给我这个,说是返回这个结构typedef struct ITEMDATA 
{
char strCellName[MAX_PATH];
double fLeft;
double fTop;
double nWidth;
double nHeight;
}ITEMDATA,*PITEMDATA;C# public struct ITEMDATA
{
public string strCellName;
public double fLeft;
public double fTop;
public double nWidth;
public double nHeight;
}
我是这样定义的,但是接受返回结构的时候 提示  "方法的类型签名与 PInvoke 不兼容。"还有就是顺便问下看见别的朋友大概是这样写, 前面[]是不是必须要加? [StructLayout(LayoutKind.Sequential)] 
public struct ITEMDATA
{
[MarshalAs(UnmanagedType.ByValTStr   ,   SizeConst   =   255)]   
public string strCellName;
[MarshalAs(UnmanagedType.R4)]   
public double fLeft;
[MarshalAs(UnmanagedType.R4)]   
public double fTop;
[MarshalAs(UnmanagedType.R4)]   
public double nWidth;
[MarshalAs(UnmanagedType.R4)]   
public double nHeight;
}
期待高手解决,已经卡了我2个小时,时间紧迫啊。100分在线等,解决立刻给分了。

解决方案 »

  1.   

    当然要加了。你用的是C#,是托管的。别人的C++程序是非托管的C++程序。因此需要用[MarshalAs(UnmanagedType.ByValTStr   ,   SizeConst   =   255)]   来表明在托管中的行为。按照别人的正确方法改一下。
      

  2.   

    public string strCellName; 
    改为public char[] strCellName;
    试试
      

  3.   

    [MarshalAs(UnmanagedType.ByValTStr,   SizeConst   =   255)]   
    public char[] strCellName;已经如上定义仍然出现   "方法的类型签名与 PInvoke 不兼容。" 对方一直是做C++的,他那边是不是也要注意什么?
      

  4.   

    public struct  ITEMDATA 
      {   
      [MarshalAs(UnmanagedType.ByValTStr , SizeConst =这里为那个输出参数的大小,此处为常量)] 
      public string strCellName;       
      }     
    是不是因为你的MAX_PATH的原因,那个传出的实际参数是多少
      

  5.   

    我也不知道,刚才他还问我C#中有没有 MAX_PATH 常量。
      

  6.   

    C#的完整点的
    ////////////////结构////////////////
    public struct ITEMDATA
    {
    [MarshalAs(UnmanagedType.ByValTStr,   SizeConst   =   5)]   
    public string strCellName;
    [MarshalAs(UnmanagedType.R4)]   
    public double fLeft;
    [MarshalAs(UnmanagedType.R4)]   
    public double fTop;
    [MarshalAs(UnmanagedType.R4)]   
    public double nWidth;
    [MarshalAs(UnmanagedType.R4)]   
    public double nHeight;
    }
    //////////////////测试的////////////
    class test1
    {
    [DllImport("TEMPL.dll", EntryPoint="GetEveryChangeCellName")]
    public static extern ITEMDATA GetEveryChangeCellName(int i);
    }
    ////////////////调用///////////////////
    private void button10_Click(object sender, System.EventArgs e)
    {
    ITEMDATA itemdata = test1.GetEveryChangeCellName(1);
    MessageBox.Show(itemdata.nHeight.ToString());
    }
      

  7.   

    再试试[StructLayout(LayoutKind.Sequential)]
    public struct  ITEMDATA  {
    public const int MAX_PATH= 那个字符数组的大小;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
    public string strCellName; MarshalAs(UnmanagedType.R8)] 
    public double fLeft; 
    MarshalAs(UnmanagedType.R8)]    
    public double fTop; 
    MarshalAs(UnmanagedType.R8)]     
    public double nWidth; 
    MarshalAs(UnmanagedType.R8)]     
    public double nHeight; }
      

  8.   

    如果C++端那边采用的为double,可以试试修改修饰为MarshalAs(UnmanagedType.R8)]
    MarshalAs(UnmanagedType.R4)] float 
    MarshalAs(UnmanagedType.R8)] double
      

  9.   

    啊啊啊  还是不行啊。。以前没接触过,这么麻烦啊。人家告诉我MAX_PATH是动态分配的。
      

  10.   

    unsafe public struct ITEMDATA
    {
    public fixed byte strCellName[MAX_PATH];
    public double fLeft;
    public double fTop;
    public double nWidth;
    public double nHeight;
    }
      

  11.   

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
            unsafe public struct ITEMDATA
            {
                public fixed byte strCellName[MAX_PATH];
                public double fLeft;
                public double fTop;
                public double nWidth;
                public double nHeight;
            }
      

  12.   

    平台调用中,可以把结构当作函数的参数,由托管平台--->到非托管平台.但应该(个人感觉),不能当作返回值,由非托管平台--->托管平台.变通的做法:把C++中函数的参数设置一个为  结构 的指针:int TestStruct(Strcut_Name* s_n){...}把C#中的函数的包装:public static extern void reInt(ref Struct_Name a);
    你试试吧,我没有时间做试验了.让C++那边改一下,多一个参数.你这儿,C#改一下,多传一个引用的参数.