【发布时间】:2011-05-22 15:34:34
【问题描述】:
我睡眼惺忪地想弄清楚为什么我不能从我的 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 参数。
感谢您的任何建议!
【问题讨论】:
-
收件人[0] = INCLUDE_ONLYUSERIDS; -- 这不会变成收件人[0] = 1;这与收件人[0] = '1' 不同; - C# 等价物是收件人[0] = (char)1;
-
收件人[4] = Char.MinValue;的目的是什么?
-
在有效的代码中,行 strcat(strcpy(&recipients[1], rID), "\n"): 生成的字符串是什么样的,即 \n 是从哪里复制的到? 512字节之后?或者它是否足够聪明,可以截断未使用的收件人 [] 的任何部分?距离我的 C++ 时代已经有一段时间了,请原谅我
-
James B - 我试图绝对确保我的字符串是多终止的,你在以后的评论中猜对了。
标签: c# c++ dll pinvoke unmanaged