ive had some problems building a correct .dll from a c++-project to my c#-project. I played around with the c++-project-properties and got a .dll file which i can add and refer to in my c# web-project. I use Dllimport to make a function call to the .dll like this:
[DllImport("Filename.dll", CharSet = CharSet.Ansi)]
static extern void Function1([MarshalAs(UnmanagedType.LPStr)] string src,
int srcLen,
[MarshalAs(UnmanagedType.LPWStr)] StringBuilder dst开发者_开发问答,
int dstLen)
The c++ function header is:
__declspec(dllimport) void Function1(unsigned char *src,
unsigned long srclen,
unsigned char *dst,
unsigned long dstlen);
Im calling Function1 in c# with this:
string strSrc = "Something";
StringBuilder strDest = new StringBuilder(kryptlen-1);
int l = strSrc.Length();
Function1(strSrc, l, strDest, l);
No exceptions or errors are occuring, though im not getting the output im expecting. The function is a decrypting method that takes an encrypted string(src) and returns the decrypted version of this (dst).
Is it the way ive generated the .dll file or is it the wrong way im calling the function? Im running out of ideas ive tried most combinations.
Thanks in advice!
C++ by default unless changed uses a caller( Cdecl ) calling convention. Your C++ code does not change the calling convention. Your C# code by default ( unless you change it ) will use a callee convention ( StdCall ).
While this might not be exactly the problem your having it still is technically incorrect. Even if you were to fix your current problem you likely will end up having a problem because of the calling convention.
No exceptions or errors are occuring, though im not getting the output im expecting. The function is a decrypting method that takes an encrypted string(src) and returns the decrypted version of this (dst).
What exactly are you getting?
The solution to the calling convention problem is to declare the calling convention.
[DllImport("Filename.dll", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] static extern void Function1([MarshalAs(UnmanagedType.LPStr)] string src, int srcLen, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder dst, int dstLen)
Where'd UnmanagedType.LPWStr
come from? There are no wide strings in the C++ declaration. You're also passing the source length twice, while the variable names suggest you need the source length and the destination buffer capacity.
If src
is encrypted data as you say, the correct p/invoke signature is probably:
[DllImport("Filename.dll", CallingConvention = CallingConvention.CDecl)]
static extern void Function1(byte[] src,
UInt32 srcLen,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder dst,
UInt32 dstLen)
Trying to force binary data into a Unicode string is a losing proposition.
After some time changing the settings back and forth i noticed that the data i had to start with was the same data i had after a decrypt and an encrypt. So I realized that the encryption/decryption was working. The problem was the data. When i had the correct data i got the correct output!
This is the end setup im stuck with now, hope it can help someone:
cryptedString = "CryptedStringFromDataBase";
StringBuilder decryptedString = new StringBuilder(300);
Decrypt(cryptedString, (uint)cryptedString.Length, decryptedString, 300);
[DllImport("Filename.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern void Decrypt(string src, UInt32 srcLen, [MarshalAs(UnmanagedType.LPStr)] StringBuilder dst, UInt32 dstLen);
精彩评论