[Mono-dev] A question about passing string-parameters when calling a Dll writing in C using p/invoke

Brandon Perry bperry.volatile at gmail.com
Tue Mar 18 17:38:24 UTC 2014


Dont use CharSet.Ansi. Try CharSet.Unicode.

Sent from a computer

> On Mar 11, 2014, at 7:55 AM, "Wang Jiteng" <imwjt at 163.com> wrote:
> 
> Nowadays I'm working on a project in which I need to call encryption and decryption  functions. These functions are written in C and have been compiled into a DLL under windows(visual studio 2010). 
> 
> The functions in the DLL(which is called Cypher.dll) are:
> unsigned long decrypt(unsigned char *reval, const char *in, unsigned long len )
> 
> and
> unsigned long encrypt(char *out, const unsigned char *data, unsigned long len)
> 
> In my C# codes, I re-write these two functions with :
>     [DllImport("Cypher.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint = "decrypt")]   
>         public  extern static uint decrypt([Out] ref byte reval,ref byte c,uint len);
> /*
> reval: the decrypted text 
> c: the cypher text to be decrypted.
> len: text length (the fellow who gave me the dll said this parameter can be assigned by any value,so I usually assigned it by c.Length)
> */
>     [DllImport("Cypher.dll", CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Cdecl, EntryPoint = "encrypt")]
>         public  extern static uint encrypt(ref byte ou,ref byte data, uint len);
> /*
> out: the encrypted cypher text
> data:the text to be encrypted, which usually is a path like "C:\\Users\\downtown\\Desktop\\something\\test" or "C:\\Users\\downtown\\Desktop\\测试集\\test" (I)
> len: text length
> */
> 
> Compared with calling the Cypher.dll direclty in C codes, the "encrypt" function always works correctly. The "decrypt" function works fine if the input parameter "data" in "encrypt" are standard ASCII charaters. 
> But when I add some CHINESE characters(I'm a Chinese progammer btw. Forgive my poor English :P ) like "C:\\Users\\downtown\\Desktop\\测试集\\test". 
> The "decrypt" result goes wrong, which is "C:\\Users\\downtown\\Desktop\\测试集\\t" (some characters in the end of the string are cut off).
> 
> if I input "C:\\Users\\downtown\\Desktop\\测试\\test", the "decrypt" is "C:\\Users\\downtown\\Desktop\\测试\\te"
> 
> It is interesting because each Chinese character takes two byte (in ANSI or UTF8). But the "decrypt" function seems retain just one byte for each Chinese character.
> So When 3 Chinese characters(测试集) exists in the string, after decrypted, they "eat" 3 bytes('e','s' and 't') at the of the string.
> When 2 Chinese characters(测试) exists in the string, after decrypted, they "eat" 2 bytes('s' and 't') at the of the string.
> 
> Dose anybody knows why that happens???
> 
> and the codes to call these fuctions above are:
> //Encrypt function;
>       public string EncryptParameters(string args)
>       {
>         byte[] plainBytes = System.Text.Encoding.Default.GetBytes(args);
>         int cypher_maxlen = args.Length*2+16;
> //prepare the cypher text byte array
>         byte[] c = new byte[cypher_maxlen];
>         int i=0;
> 
>         CFunction.encrypt(ref c[0],ref plainBytes[0], (uint)args.Length);
> 
>         for(i=0;c[i]!=0 && i<cypher_maxlen;i++)//;
>                 Console.Write(c[i]+" ");
> 
>         string cypher_str = System.Text.Encoding.Default.GetString(c, 0, i);
>         return cypher_str;
>       }
> 
> //Decrypt Function
>       public string DecryptParameters(string args)
>       {
>         int plain_maxlen = args.Length;
> 
> //add a '\0' to the end, or the "decrypt" function goes wrong sometime.
>         string args_with_end = args + "\0";
>         byte[] cypherBytes = System.Text.Encoding.Default.GetBytes(args_with_end);
>         int i=0;
> 
> //prepare the byte array of decrypted text
>         byte[] p = new byte[plain_maxlen];
>         CFunction.decrypt(p,cypherBytes,(uint)cypherBytes.Length);
> 
>         for(i=0;p[i]!=0 && i<plain_maxlen;i++);
>         string plain_str = System.Text.Encoding.Default.GetString(p, 0, i);
>         return plain_str;
>       }
> 
> and I call these two functions above like:
>          string cypher_args = EncryptParaments(init_args);
>          string plain_args = DecryptParaments(cypher_args);
> and the string plain_args are not always correct as I mentioned. 
> 
> Thanks.
> 
> 
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-devel-list/attachments/20140318/e75d2a2e/attachment.html>


More information about the Mono-devel-list mailing list