1

我在调用 ac# 应用程序内的 c++ dll 中的函数时遇到问题。我在 c# 中调用函数,如下所示:

[DllImport("cryptopp.dll")]
public static extern IntPtr RSAEncryptString(string filename, string seed, string message);

它正在 c++ dll 中导出,如下所示。

extern "C" __declspec(dllexport) const char* __cdecl RSAEncryptString(const char *pubFilename, const char *seed, const char *message);

但是,当我尝试调用它时,我得到的是“外部组件引发了异常”。例外,这根本不是描述性的,而且非常无益。

当我在导出查看器中拉出 dll 时,它会显示所有其他具有完全量化声明的导出函数(IE public: void __cdecl CryptoPP::X509PublicKey::`vbase destructor'(void) __ptr64 ),除了我的函数调用,它只显示函数名称 RSAEncryptString。

这是我能看到的唯一可能的问题,除了可能在 c# 端使用无效声明错误调用函数。我使用 System.Runtime.InteropServices.Marshal 错了吗?

请帮助<3,并在此先感谢。

4

2 回答 2

3

我认为您需要将第一行更改为:

[DllImport("cryptopp.dll",
    CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

如果您想获得非常具有描述性的内容,还可以添加以下内容:

public static extern IntPtr RSAEncryptString(
    [In, MarshalAs(UnmanagedType.LPStr)] string filename,
    [In, MarshalAs(UnmanagedType.LPStr)] string seed,
    [In, MarshalAs(UnmanagedType.LPStr)] string message);

IIRC 认为CharSet应该为您处理编码问题,但如果没有,请使用MarshalAs也,如上所示。


编辑:

哦,我想我明白了为什么你仍然会出错!您的代码仍然存在上述问题,但仍然出错,因为您无法返回string对象,因为它不是托管对象;您需要返回一个指针(如IntPtr),然后使用Marshal.PtrToStringAnsi

(起初回答这个问题时,我并没有真正看你的返回类型。)

于 2011-01-19T15:37:14.907 回答
0

看来您正在尝试将类型const char *(an LPCSTR) 的返回值存储到一个IntPtr类型中(通常用于HANDLEs,而不是LPSTRs。)试试这个:

[DllImport("cryptopp.dll", CharSet = CharSet.Auto)]
public static extern String RSAEncryptString(String filename, String seed, String message);

另请记住,如果要写入任何参数,则需要out在其类型之前添加,即..., out String message)

于 2011-01-19T16:00:47.013 回答