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

Wang Jiteng imwjt at 163.com
Tue Mar 11 12:55:42 UTC 2014


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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-devel-list/attachments/20140311/427cd1f8/attachment-0001.html>


More information about the Mono-devel-list mailing list