http://blog.163.com/xiaozhi797@126/blog/static/62440288201231341344512/

解决方案 »

  1.   

     const char *pszBuffer,DWORD dwSize,chsr **pszOutPut,DWORD *pdwRecv
    这个不是字符串,是字节流IntPtr pszBuffer, int dwSize, out IntPtr pszOutPut, out pdwRecv
    IntPtr里面的东西可以使用Marshal类里面的Copy函数拿出来
      

  2.   

    输入参数的话string应该也可以,指定对CharSet就行。输出参数要用IntPtr或StringBuider。试试这样
    string sendStr, UInt32 sendSize, StringBuider recvStr, ref UInt32 recvSize
      

  3.   

    string sendStr, int sendSize, ref string recvStr, ref int recvSize
    上面这个是对应的正确声明
    其实楼主的这个error很多时候都是由于CallingConvention引起的
    这样:
    [DllImport("...dll", CallingConvention = CallingConvention.Cdecl)]
      

  4.   

    //c++:HANDLE(void   *)       ----   c#:System.IntPtr        
    //c++:Byte(unsigned   char)   ----    c#:System.Byte         
    //c++:SHORT(short)           ----    c#:System.Int16         
    //c++:WORD(unsigned short) ---  c#:System.UInt16        
    //c++:INT(int)                 ----    c#:System.Int16        
    //c++:INT(int)                  ----    c#:System.Int32         
    //c++:UINT(unsigned int)  ----    c#:System.UInt16        
    //c++:UINT(unsigned int) ----    c#:System.UInt32        
    //c++:LONG(long)             ----    c#:System.Int32         
    //c++:ULONG(unsigned long) --   c#:System.UInt32         
    //c++:DWORD(unsigned long) --  c#:System.UInt32         
    //c++:DECIMAL         ----    c#:System.Decimal         
    //c++:BOOL(long)        ----    c#:System.Boolean         
    //c++:CHAR(char)       ----    c#:System.Char  
           
    //c++:LPSTR(char *)      ----    c#:System.String         
    //c++:LPWSTR(wchar_t *)  ----    c#:System.String         
    //c++:LPCSTR(const char *)  ---   c#:System.String         
    //c++:LPCWSTR(const wchar_t *) ---   c#:System.String         //c++:PCAHR(char *)   ----   c#:System.String     
        
    //c++:BSTR       ----    c#:System.String       
      
    //c++:FLOAT(float)      ----    c#:System.Single         
    //c++:DOUBLE(double)    ----    c#:System.Double         
    //c++:VARIANT           ----    c#:System.Object         
    //c++:PBYTE(byte   *)   ----    c#:System.Byte[]         
    //c++:BSTR      ----    c#:StringBuilder    
        
    //c++:LPCTSTR   ----    c#:StringBuilder  
          
    //c++:LPCTSTR   ----    c#:string        //c++:LPTSTR    ----    
    c#:[MarshalAs(UnmanagedType.LPTStr)] string  
           
    //c++:LPTSTR     ----    c#:StringBuilder 
         
    //c++:LPCWSTR   ----    c#:IntPtr        //c++:BOOL      ----    c#:bool           //c++:HMODULE   ----    c#:IntPtr        
        
    //c++:HINSTANCE ----    c#:IntPtr        
     
    //c++:结构体    ----    c#:public struct 结构体{}; 
            
    //c++:结构体 **变量名   ----    c#:out 变量名   //C#中提前申明一个结构体实例化后的变量名      
     
    //c++:结构体 &变量名    ----    c#:ref 结构体 变量名                 
    //c++:WORD      ----    c#:ushort        //c++:DWORD     ----    c#:uint        //c++:DWORD     ----    c#:int        //c++:UCHAR     ----    c#:int        //c++:UCHAR     ----    c#:byte        //c++:UCHAR*    ----    c#:string      
      
    //c++:UCHAR*    ----    c#:IntPtr        //c++:GUID      ----    c#:Guid        //c++:Handle    ----    c#:IntPtr        //c++:HWND      ----    c#:IntPtr        //c++:DWORD     ----    c#:int        //c++:COLORREF  ----    c#:uint       
     
    //c++:unsigned char     ----    c#:byte      
      
    //c++:unsigned char *   ----    c#:ref byte       
     
    //c++:unsigned char *   ----    
    c#:[MarshalAs(UnmanagedType.LPArray)] byte[]        
    //c++:unsigned char *   ----    
    c#:[MarshalAs(UnmanagedType.LPArray)] Intptr        
    //c++:unsigned char &   ----    c#:ref byte  
          
    //c++:unsigned char 变量名      ----    c#:byte 变量名        
    //c++:unsigned short 变量名    ----   c#:ushort 变量名        
    //c++:unsigned int 变量名       ----    c#:uint 变量名        
    //c++:unsigned long 变量名     ----    c#:ulong 变量名        
    //c++:char 变量名       ----    c#:byte 变量名 
      
    //c++中一个字符用一个字节表示,c#中一个字符用两个字节表示        //c++:char 数组名[数组大小]     ----    
    c#:MarshalAs(UnmanagedType.ByValTStr, SizeConst = 数组大小)]        
       
    //c++:char *            ----    c#:string       
     
    //c++:char *            ----    c#:StringBuilder
        
    //c++:char *变量名      ----    c#:ref string 变量名        
    //c++:char *输入变量名  ----    c#:string 输入变量名        
    //c++:char *输出变量名  ----    
    c#:[MarshalAs(UnmanagedType.LPStr)] StringBuilder 输出变量名      
      
    //c++:char **           ----    c#:string     
       
    //c++:char **变量名     ----    c#:ref string 变量名        
    //c++:const char *      ----    c#:string   
         
    //c++:char[]            ----    c#:string     
       
    //c++:char 变量名[数组大小]     ----    
    c#:[MarshalAs(UnmanagedType.ByValTStr,SizeConst=数组大小)] public string 变量名;     //c++:struct 结构体名 *变量名   ----    c#:ref 结构体名 变量名        //c++:委托 变量名   ----    c#:委托 变量名    
        
    //c++:int       ----    c#:int        //c++:int       ----    c#:ref int        //c++:int &     ----    c#:ref int      
      
    //c++:int *     ----    c#:ref int      //C#中调用前需定义int 变量名 = 0;      
      
    //c++:*int      ----    c#:IntPtr        //c++:int32 PIPTR *     ----    c#:int32[]   
         
    //c++:float PIPTR *     ----    c#:float[]       
             
    //c++:double** 数组名          ----    c#:ref double 数组名        //c++:double*[] 数组名          ----    c#:ref double 数组名        //c++:long          ----    c#:int        //c++:ulong         ----    c#:int           
         
    //c++:UINT8 *       ----    c#:ref byte      
     
    //C#中调用前需定义byte 变量名 = new byte();                
    //c++:handle    ----    c#:IntPtr        //c++:hwnd      ----    c#:IntPtr         
                   
    //c++:void *    ----    c#:IntPtr          
          
    //c++:void * user_obj_param    ----    
    c#:IntPtr user_obj_param        //c++:void * 对象名称    ----    
    c#:([MarshalAs(UnmanagedType.AsAny)]Object 对象名称                //c++:char,INT8,SBYTE,CHAR  --  c#:System.SByte          
    //c++:short, short int, INT16, SHORT                        ----    c#:System.Int16        
      
    //c++:int, long, long int,INT32, LONG32, BOOL , INT  ----    c#:System.Int32       
       
    //c++:__int64,INT64,LONGLONG                           --  c#:System.Int64          //c++:unsigned char, UINT8, UCHAR , BYTE               ----    c#:System.Byte          //c++:unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t  ----  c#:System.UInt16          //c++:unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT     
     ----    c#:System.UInt32          //c++:unsigned __int64, UINT64, DWORDLONG, ULONGLONG                            
    ----    c#:System.UInt64          //c++:float,FLOAT    --  c#:System.Single          //c++:double, long double, DOUBLE                          ----    c#:System.Double          //Win32 Types        ----  CLR Type       
               
    //Struct需要在C#里重新定义一个Struct    
        
    //CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);       
     
    //unsigned char** ppImage替换成IntPtr ppImage        
    //int& nWidth替换成ref int nWidth       
     
    //int*, int&, 则都可用 ref int 对应      
      
    //双针指类型参数,可以用 ref IntPtr       
     
    //函数指针使用c++: typedef double (*fun_type1)(double); 对应 c#:public delegate double  fun_type1(double);        //char* 的操作c++: char*; 对应 c#:StringBuilder;        
    //c#中使用指针:在需要使用指针的地方 加 unsafe        //unsigned   char对应public   byte    
        
      

  5.   

    c++的char是1字节
    c#的char是2字节,怎么会对应呢?
      

  6.   


    首先感谢5楼,的确是需要这个CallingConvention。
    但是,本人确实是对C++不太熟悉,我加上这句之后,虽然不报错了,但是却没有得到正确的返回值。
    我想问问是不是我发送的数据错了呢?因为原本C++里的代码是发送一个结构体数据的。代码如下:        DWORD dwSize;
    PUBLICFunction pFunc;
    pFunc.enumV =GET_ACTIVESIGNALS;
            /* 这里的GET_ACTIVESIGNALS = 32,但由于它是个枚举型,我不知道是否可以直接用int型的32?*/
    dwSize=0;
    *pOutput=NULL;
    RSendTo((const char*)&pFunc,(DWORD)(DWORD_PTR)sizeof(pFunc),pOutput,&dwSize);其中对于PUBLICFumction的定义如下:typedef struct{
    enumPUBLIC enumV;
    }PUBLICFunction,*PPUBLICFunction;
    那我C#的代码里是不是也应该用一个结构体,然后转换为数据流传参呢?如果是的话,这个时候,参数的类型是否要改变呢?谢谢各位!!
      

  7.   

    你这里面完全看不到String的影子,你用String传递进去肯定是得不到想要的结果了,用int类型都比那个好。至于输出,看不出它对应了什么类型,只有一个dwSize来说明这个类型的长度,因此你只能用byte[]来获取输出,或者直接Intptr得到输出的地址后,自己Marshal.Copy
      

  8.   


    ((const char*)&pFunc 这个不是string型的么?pFunc在这里是个结构体啊~~
      

  9.   

    在C++里面,char不一定是字符的意思,等价于C#的byte,要看具体情况,因此char*就等价于C#的byte[],而后面又跟着一个参数来指定前面这个const char*的长度,可见更不可能是字符串了,因为C++里面的字符串是以0x00结尾的二进制数组,遇到0x00自动认为是字符串的结束标志,不需要指定长度,它却指定了,因此可以看出那个不代表传递的是字符串。
      

  10.   


    原来如此啊~~受教了!!
    那我想是byte[]应该没错了,因为RSendTo这个方法最终是通过socket来收发消息。只是不理解这个const在这里又起什么作用呢。
      

  11.   

    const等价于C#的readonly 关键字,这里起什么作用不清楚。
      

  12.   

    在C++ 中是指常量,在函数内是不能修改该值的。不过封装成API能成功吗?因为C中没有这个东西哈所以不用理会它,
      

  13.   

    感谢 11楼qldsrx 和 5楼foreachif !!!
    最后是得到Intptr输出的地址后,在用Marshal.Copy转换到byte[]里的。
    因为如果直接用byte[]来获得输出的话只能得到第一byte[0]的值。恐怕原来的C++函数中返回的是地址吧…
      

  14.   

    SamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamplesSamples