我在调用 c# 应用程序内的 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);
但是,当我尝试调用它时得到的是“外部组件引发了异常”。异常(exception),它根本不是很具描述性,而且非常无益。
当我在导出查看器中拉出 dll 时,它会显示所有其他具有完全量化声明的导出函数(即 public: void __cdecl CryptoPP::X509PublicKey::`vbase destructor'(void) __ptr64 ),除了我正在调用的函数,它只显示函数名称 RSAEncryptString。
这是我能看到的唯一可能的问题,除了可能会在 C# 端错误地调用带有无效声明的函数。我使用的 System.Runtime.InteropServices.Marshal 错了吗?
请帮助 <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
!
(我一开始回答这个问题的时候并没有真正看你的返回类型。)
关于c# - 通过 C++ 64 位 dll 在 64 位 .net 应用程序中调用 PInvoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4737169/