我的这个程序,使用c#调用c++编写的dll,总是出现以下这个问题,那位高手能够帮帮忙,小女子在此先感谢了。 
大家就救我吧。 c++编写的dll中的函数 
void  EFSgetUsrThesaurus ( pUsrDicFileNameTable  DicFlNmTbl, 
pUsrKeyWordTable      KeyWdTbl, 
pUsrThesaurusTable    ThTbl, 
EFSDICSTATUS  *EFS_dicstatus ); c++中的结构体 typedef struct{ 
int  Cnt; 
struct{ 
char Name[MAX_WORD_LENGTH+1]; 
} *Data; 
} UsrThesaurusTable, *pUsrThesaurusTable; typedef struct{ 
int  Cnt; 
struct{ 
char  Name[MAX_WORD_LENGTH+1]; 
int  GroupCnt; 
struct{ 
char FileName[MAX_PATH_LENGTH+1]; 
int  Number; 
int  HeadIndex; 
int  ExpandCnt; 
} *Group; 
} Data[MAX_KEYWORD_CNT]; 
} UsrKeyWordTable, *pUsrKeyWordTable; typedef struct{ 
int  Cnt; 
struct{ 
char Name[MAX_WORD_LENGTH+1]; 
} *Data; 
} UsrThesaurusTable, *pUsrThesaurusTable; typedef struct{ 
int retcode; 
int word_count; 
} EFSDICSTATUS; 
我现在需要在c#中调用这个函数 
以下是我写的代码 c#中定义的结构体 

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct DicFileName 
    { 
        public StringBuilder  Name;    
    }     [StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct EFSDICSTATUS { 
        public int retcode;          
        public int word_count;            
    } 
    
    [StructLayout(LayoutKind.Sequential, Pack = 1)]  
    public struct GroupInfo { 
        public StringBuilder FileName; 
        public int Number;    
        public int HeadIndex; 
        public int ExpandCnt; 
    } 
  
    [StructLayout(LayoutKind.Sequential, Pack = 1)]  
    public struct Keyword { 
        public StringBuilder Name;  
        public int GroupCnt; 
        public GroupInfo Group; 
    }     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]  
    public struct Thesaurus 
    { 
        //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1000)] public string Name;  
        public StringBuilder Name; 
    }     [StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct pUsrDicFileNameTable 
    { 
        public int Cnt; 
        public DicFileName[] Data; 
    }     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]  
    public struct pUsrKeyWordTable 
    { 
        public int Cnt; 
        public Keyword[] Data; 
    }     [StructLayout(LayoutKind.Sequential, Pack = 1)]  
    public struct pUsrThesaurusTable 
    { 
        public int Cnt;  
        public Thesaurus Data; 
    } 
程序中的调用 
[DllImport("EFSdic.dll")] 
public static extern void EFSgetUsrThesaurus(pUsrDicFileNameTable udfnt, ref pUsrKeyWordTable ukwt, ref pUsrThesaurusTable utt, ref  EFSDICSTATUS err); public StringBuilder _sSystemDicName = new StringBuilder(@"C:\inputproject\chenliang.txt");  
public StringBuilder _sCustomerDicName = new StringBuilder (@"C:\inputproject\aaa.txt");  private void but_Search_Click(object sender, EventArgs e) 
        

            DataTable dt = new DataTable(); 
            dt.Columns.Add("WordItem");             string _strKeywords = this.txt_Search.Text;             pUsrDicFileNameTable udfnt = new pUsrDicFileNameTable();//辞書ファイル情報 
            DicFileName[] files=new DicFileName [1]; 
            files[0].Name = _sCustomerDicName; 
            udfnt.Cnt = 1; 
            udfnt.Data = files;             pUsrKeyWordTable ukwt = new pUsrKeyWordTable();//検索結果情報 
            Keyword[] key=new Keyword[1]; 
            GroupInfo g = new GroupInfo(); 
            key[0].Name = new StringBuilder(_strKeywords); 
            key[0].GroupCnt = 0; 
            key[0].Group = g; 
            ukwt.Cnt = 1; 
            ukwt.Data = key;             pUsrThesaurusTable utt = new pUsrThesaurusTable(); 
            utt.Cnt = 0; 
            utt.Data = new Thesaurus(); 
            utt.Data.Name = new StringBuilder(""); 
          
            EFSDICSTATUS err = new EFSDICSTATUS();             EFSgetUsrThesaurus(udfnt, ref ukwt, ref  utt, ref err); 
//此行总是说SystemThesaurus.pUsrThesaurusTable中的Data类型有一些问题 
            
if (err.retcode  < 0) 
            { 
                MessageBox.Show(HandleClass.ErrorChoice(err.retcode )); 
            }             for (int i = 0; i < utt.Cnt; i++) 
            { 
                string[] strResult = new string[1]; 
                //strResult[0] = utt.Data[i].Name; 
                dt.Rows.Add(strResult); 
            }             frm_Result frmResult = new frm_Result(); 
            frmResult.ResultList = dt; 
            frmResult.Show();            } 谁能帮我解决一下,实在是太着急了,呜呜呜呜

解决方案 »

  1.   

    UsrThesaurusTable中的匿名结构体
    [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
    public struct UsrThesaurusTableData 
    {
    [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=MAX_WORD_LENGTH+1 )]//自己替换MAX_WORD_LENGTH
    public String  Name ;
    }
    [ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
    public struct UsrThesaurusTable
    {
    public int Cnt;
    public IntPtr Data;
    }匿名结构体真多,剩下自己按照这个翻译把。
      

  2.   

    替换后
    c#的结构体是 [StructLayout(LayoutKind.Sequential,  CharSet = CharSet.Ansi)] 
        public struct pUsrDicFileNameTable
        {
            public int Cnt; 
             public pUsrDicFileNameTableData[] Data;
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrDicFileNameTableData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
            public String Name;    
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrKeyWordTable
        {
            public int Cnt; 
            public pUsrKeyWordTableData[] Data; 
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrKeyWordTableData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
            public String Name;   
            public int GroupCnt; 
            public IntPtr  Group;
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrKeyWordTableDataData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
            public String FileName; 
            public int Number;    
            public int HeadIndex; 
            public int ExpandCnt; 
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrThesaurusTable
        {
            public int Cnt;   
            public IntPtr Data;
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct UsrThesaurusTableData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
            public String Name;
        }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct EFSDICSTATUS
        {
            public int retcode;          
            public int word_count;             
        }调用的代码
    namespace SystemThesaurus
    {
        public partial class frm_Main : Form
        {
            [DllImport("EFSdic.dll")]
            public static extern void EFSgetUsrThesaurus(pUsrDicFileNameTable udfnt, ref pUsrKeyWordTable ukwt, ref pUsrThesaurusTable utt, ref  EFSDICSTATUS err);        public String _sCustomerDicName =@"C:\inputproject\chenliang.txt";   
             public frm_Main()
            {
                InitializeComponent();
            }        private void but_Search_Click(object sender, EventArgs e)
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("WordItem");
                String _strKeywords = this.txt_Search.Text;
                pUsrDicFileNameTable udfnt = new pUsrDicFileNameTable();
                  pUsrDicFileNameTableData[] files = new pUsrDicFileNameTableData [1];
                files[0].Name = _sCustomerDicName;
                udfnt.Cnt = 1;
                udfnt.Data = files;            pUsrKeyWordTable ukwt = new pUsrKeyWordTable();
                  pUsrKeyWordTableData[] key = new pUsrKeyWordTableData[1];
                
                key[0].Name = _strKeywords;
                key[0].GroupCnt = 0;
                key[0].Group = IntPtr .Zero ;
                ukwt.Cnt = 1;
                ukwt.Data = key;            pUsrThesaurusTable utt = new pUsrThesaurusTable();
                utt.Cnt = 0;
                utt.Data = IntPtr.Zero;            EFSDICSTATUS err = new EFSDICSTATUS();            EFSgetUsrThesaurus(udfnt, ref ukwt, ref  utt, ref err);            if (err.retcode  < 0)[/color[color=#008000]]//此处还是有错误,参数不正确(HRESULT からの例外: 0x80070057 (E_INVALIDARG))            {
                    MessageBox.Show(HandleClass.ErrorChoice(err.retcode ));
                }            for (int i = 0; i < utt.Cnt; i++)
                {
                    StringBuilder[] strResult = new StringBuilder[1];
                    //strResult[0] = utt.Data[i].Name ;
                    dt.Rows.Add(strResult.ToString ());
                }            frm_Result frmResult = new frm_Result();
                frmResult.ResultList = dt;
                frmResult.Show();            }        private void but_Cancel_Click(object sender, EventArgs e)
            {
                this.Close();
            }
        }
    }
      

  3.   

    执行 regsrv32 abc.dll 注册你的com组件
      

  4.   

    注册了也不行,还是那个错误参数不正确(HRESULT からの例外: 0x80070057 (E_INVALIDARG))
      

  5.   

    c++中的int 是2 字节,c#int是4字节,所以,你的问题出在数据类型的定义上面,改成长度对应的数据类型,注意参数传递方式,堆栈和堆是有区别的;引用类型传递的时候要把固定地址住
      

  6.   

    还是不行,我把int 都改成了int16,还是同样的错误
    我已经把
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrKeyWordTableDataData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
            public String FileName; 
            public int Number;    
            public int HeadIndex; 
            public int ExpandCnt; 
        }

    改成了
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
        public struct pUsrKeyWordTableDataGroup
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
            public String FileName; 
            public int Number;    
            public int HeadIndex; 
            public int ExpandCnt; 
        }
      

  7.   

    c++中的int 是2 字节,c#int是4字节,所以,你的问题出在数据类型的定义上面,改成长度对应的数据类型,注意参数传递方式,堆栈和堆是有区别的;引用类型传递的时候要把固定地址住
    ---------------------------------------------
    c++中的int 是2 字节????????哪个老师这么讲的,我要把他轰下去!int是多少个字节跟编译器有关,DOS下使用Turbo C(这个古董,还有人知道否?)编码,确实是认为int是16位,编译成的指令也确实是实模式16位代码;而在nt4.0后用vs编写,int都是32位的。
      

  8.   

    用CLR类库把要调用的函数封装在一个类里,然后添加生成的dll文件即可.
      

  9.   

    很疑惑的一点是大家为什么都喜欢用C#调用C++的dll?
      

  10.   

    这个dll不是公司自己做的,只是公司要来使用,所以一直都弄不好,20楼的高手能不能帮我看看程序