繁体   English   中英

难以从C#调用非托管dll

[英]Difficulty calling unmanaged dll from C#

我正试着弄清楚为什么我不能在C#应用程序中使用旧的C ++ .dll调用外部方法。

这是函数头:

int __export FAR PASCAL SimplePGPEncryptFile(
                                      HWND hWnd1,
                                      LPSTR InputFileName,
                                      LPSTR OutputFileName,
                                      BOOL SignIt,
                                      BOOL Wipe,
                                      BOOL Armor,
                                      BOOL TextMode,
                                      BOOL IDEAOnly,
                                      BOOL UseUntrustedKeys,
                                      LPSTR RecipientList,
                                      LPSTR SignerKeyID,
                                      int SignerBufferLen,
                                      LPSTR SignerPassphrase,
                                      int SignerPwdBufferLen,
                                      LPSTR IDEAPassphrase,
                                      int IDEAPwdBufferLen,
                                      LPSTR PublicKeyRingName,
                                      LPSTR PrivateKeyRingName);

这是我的C#声明:

        [DllImport("smplpgp_32.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern int SimplePGPEncryptFile(
        IntPtr hWnd1,
        [MarshalAs(UnmanagedType.LPStr)] string InputFileName,
        [MarshalAs(UnmanagedType.LPStr)] string OutputFileName,
        bool SignIt,
        bool Wipe,
        bool Armor,
        bool TextMode,
        bool IDEAOnly,
        bool UseUntrustedKeys,
        [MarshalAs(UnmanagedType.LPStr)] string RecipientList,
        [MarshalAs(UnmanagedType.LPStr)] string SignerKeyID,
        int SignerBufferLen,
        [MarshalAs(UnmanagedType.LPStr)] string SignerPassphrase,
        int SignerPwdBufferLen,
        [MarshalAs(UnmanagedType.LPStr)] string IDEAPassphrase,
        int IDEAPwdBufferLen,
        [MarshalAs(UnmanagedType.LPStr)] string PublicKeyRingName,
        [MarshalAs(UnmanagedType.LPStr)] string PrivateKeyRingName);

当我调用此方法时,我得到以下两个错误之一(在标头中声明):

#define SIMPLEPGPENCRYPTFILE_RECIPIENTLISTDOESNOTENDWITHNEWLINE    408
#define SIMPLEPGPENCRYPTFILE_RECIPIENTLISTDOESNOTSTARTWITHGOODCODECHAR   409

这也被定义为标题中的常量:

#define INCLUDE_ONLYUSERIDS 1

这是已知可以调用此函数的C ++代码:

    char recipients[512];
recipients[0] = INCLUDE_ONLYUSERIDS;
strcat(strcpy(&recipients[1], rID), "\n"); \\ rID is equal to "CA"
return 0 == SimplePGPEncryptFile(INI.m_hWnd,
    (char*)plain, (char*)cipher,
    0,
    0,
    1,
    0,
    0,
    1, // UseUntrustedKeys
    recipients,
    0, 0,
    0, 0,
    0, 0,
    PGPKM.pub, 0); //PGPKM.pub is declared earlier

将此传递给'RecipientList'参数会给出'409'错误:

string recipientList = "1CA\n\0";

将此传递给'RecipientList'参数会给出'408'错误:

char[] recipients = new char[512];
recipients[0] = '1';
recipients[1] = 'C';
recipients[2] = 'A';
recipients[3] = '\n'; // also tried '\r', then '\n'
recipients[4] = Char.MinValue;
string paramValue = recipients.ToString();

我可以发现一个明显的疏忽吗? 我觉得我已经拥有了解决这个问题所需要的一切,但没有任何工作能够按预期进行。

旁注:我在同一个.dll中成功调用了一个不同的函数。 此外,我已经尝试使用StringBuilder来构造RecipientList参数。

谢谢你的任何建议!

TLDR:

string recipientList = (char) 1 + "CA\n\0";

根据Jeffora的评论进行了一些挖掘...他可能是对的,我的第一个建议可能不会给你买任何东西。 我写了一些测试代码,这是我发现的:

当您使用此代码时:

string recipientList = "1CA\n\0";

在封送为LPStr之后,您在函数内部结束的字节是:

49-67-65-10-0

这看起来像你想要的。

当您使用此代码时:

char[] recipients = new char[512];
recipients[0] = '1';
recipients[1] = 'C';
recipients[2] = 'A';
recipients[3] = '\n'; // also tried '\r', then '\n'
recipients[4] = Char.MinValue;
string paramValue = recipients.ToString();

在封送为LPStr之后,在函数内部获得的字节是:

83-121-115-116-101-109-46-67-104-97-114-91-93

哪个是“System.Char []”的ASCII。 因此,您肯定需要使用编码器将char []转换为您想要的字符串。

至于为什么第一个字符串不起作用...我怀疑你的DLL真的在寻找值'1',而不是'1'(49)的ascii字符。 在有效的代码中,您说:

recipients[0] = INCLUDE_ONLYUSERIDS;

其中INCLUDE_ONLYUSERIDS = 1

尝试这个:

string recipientList = (char) 1 + "CA\n\0";


原始答案:

  

您是否尝试更改调用约定? 在C ++中,您使用pascal调用约定声明函数,并在C#中声明为stdcall。 调用约定必须匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM