c# - 通过 C++ 64 位 dll 在 64 位 .net 应用程序中调用 PInvoke

标签 c# c++ c#-4.0 pinvoke dllexport

我在调用 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/

相关文章:

c# - 首先使用 ASP.NET MVC 4 迁移代码的foreignkey

c# - 如何找到两组不连续时间的交集?

c++ - 使用 C++ QT 创建一个 ListView

c++ - 将 unordered_map 设置为 unordered_map 的值

c++ - Protobuf 生成的 C++ 类无法针对 iOS 进行编译,错误为 "Only virtual member functions can be marked ' final'"

asp.net - 内存转储不显示 IIS 崩溃的详细信息

c# - 如何使用 Win32 API 在 TreeView 中选择一个项目

c#-4.0 - C#三元运算符返回不同的类型

c# - 我可以限制进程的 RAM 使用量吗?

c# - 防止意外重新枚举 IEnumerable 的技术?