Reputation: 307
What is the equivalent C# parameter type to be used for below C com function?
For the signature below I'm getting the error:
This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
C#
[DllImport("Sn62.dll")]
public static extern int GetLicenseNo(string lpszLicenseKey,
string lpszEncryptionKey,
string lpBuffer,
ushort wBufferSize);
C code
#define _SAL2_Source_(Name, args, annotes) _SA_annotes3(SAL_name, #Name, "", "2") _Group_(annotes _SAL_nop_impl_)
#define _Null_terminated_ _SAL2_Source_(_Null_terminated_, (), _Null_terminated_impl_)
typedef int BOOL;
typedef _Null_terminated_ CHAR *LPSTR;
typedef unsigned short WORD;
__declspec(dllexport) BOOL SN_GetLicenseNo(LPSTR lpszLicenseKey,LPSTR lpszEncryptionKey,LPSTR lpBuffer,WORD wBufferSize);
BOOL GetLicenseNo(LPSTR lpszLicenseKey, LPSTR lpszEncryptionKey, LPSTR lpszBuffer, WORD wBufferSize)
{
struct t_license *lp;
BOOL bRet;
if (wBufferSize<SIZE_LICENSENO + 1)
return(FALSE);
ClearText(lpszLicenseKey, lpszEncryptionKey);
lp = (struct t_license *)DecodeBuffer;
bRet = TRUE;
CopyString(lpszBuffer, lp->LicenseNo, SIZE_LICENSENO); //lpszBuffer is used to return value.
return(bRet);
}
Upvotes: 0
Views: 129
Reputation: 11273
I think you are close, you just need to tell the marshalling system what kind of string to marshal it as:
[DllImport("Sn62.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetLicenseNo([MarshalAs(UnmanagedType.LPStr)]string lpszLicenseKey,
[MarshalAs(UnmanagedType.LPStr)]string lpszEncryptionKey,
[MarshalAs(UnmanagedType.LPStr)]string lpBuffer,
ushort wBufferSize);
That way it knows exactly how to transform the data.
Edit: You may also need to specify the calling convention to match the type of export that you are using, see the CallingConvention
in the DllImport
attribute.
Based on what Hans Passant says, this is probably more correct:
[DllImport("Sn62.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetLicenseNo(StringBuilder lpszLicenseKey,
StringBuilder lpszEncryptionKey,
StringBuilder lpBuffer,
ushort wBufferSize);
Which you would call with:
ushort wBufferSize = 250; //Set to the size you need
StringBuilder licKey = new StringBuilder(wBufferSize);
StringBuilder encKey = new StringBuilder(wBufferSize);
StringBuilder buffer = new StringBuilder(wBufferSize);
//Intialize values here...
GetLicenseNo(licKey, encKey, buffer, wBufferSize);
Upvotes: 1