我在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);
但是,当我尝试调用此方法时,得到的是“外部组件引发了异常”。异常,这根本不是描述性的,并且非常无益。
当我在导出查看器中拉起dll时,它会显示具有完全量化声明的所有其他导出函数(IE public:void __cdecl CryptoPP::X509PublicKey::`vbase destructor'(void)__ptr64),但我使用的函数除外调用,仅显示函数名称RSAEncryptString。
这是我看到的唯一可能的问题,除了可能会错误地在C#端使用无效的声明调用该函数。我使用System.Runtime.InteropServices.Marshal错了吗?
请帮助
最佳答案
我认为您需要将第一行更改为:
[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在64bit .net应用程序中PInvoke,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4737169/