Dll导入Marshal C ++字符串问题

时间:2013-12-11 21:51:35

标签: c# c++ dll import marshalling

这是我试图导入的DLL函数的签名

typedef char*(*DLLFUNC_Encrypt)(const char*, unsigned int, unsigned int&);

这是我的C#代码

[DllImport("AuthCrypto.dll", EntryPoint = "Encrypt")]
public static extern IntPtr Encrypt(IntPtr data, int size, ref int mode);

public static string EncryptData(string data)
{
    int mode = 5;
    IntPtr dataIntPtr = Marshal.StringToHGlobalAnsi(data);
    IntPtr data_enc = CryptoAPI.Encrypt(dataIntPtr, data.Length, ref mode);

    return Marshal.PtrToStringAnsi(data_enc);
}

这是我的例外:

  

对PInvoke函数'CryptoAPI :: Encrypt'的调用使得不平衡   堆。这可能是因为托管的PInvoke签名没有   匹配非托管目标签名。检查是否正在通话   PInvoke签名的约定和参数与目标匹配   非托管签名。

1 个答案:

答案 0 :(得分:1)

看起来您需要指定要使用的调用约定。由于on DLLFUNC_Encrypt没有显式设置,编译器使用其默认值。哪个调用约定被认为是默认值取决于您的编译器设置(对于Visual Studio,如果您没有更改它,则为cdecl。)

您可以通过显式指定调用约定DLLFUNC_Encrypt来解决这个问题:

typedef char*(*__cdecl DLLFUNC_Encrypt)(const char*, unsigned int, unsigned int&);

并相应调整您的平台调用:

[DllImport("AuthCrypto.dll", EntryPoint = "Encrypt", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Encrypt(IntPtr data, int size, ref int mode);

您可以传递给DllImport的通话约定在CallingConvention enumeration

中定义

我刚刚读到你正在调用的DLL是封闭源代码。如果你不能在DLL中指定调用约定,你可以查看你是否在文档中找到库使用的调用约定,或者你可以测试直到你找到一个有效的约会(它可能是StdCallCdecl)。