[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