【发布时间】:2021-04-26 21:59:06
【问题描述】:
这个问题把我逼疯了......只是说。
我的公司有一个旧版 C++ 库,我的任务是创建一个 .NET 包装器。
我没有 C++ 或 P/Invoke 的经验,所以我开始尝试一个简单的方法。
我已经阅读了official documentation,我还找到了a nice tutorial。
但是,我发现消费应用程序的目标 .NET 框架有所不同。
本教程中的 P/Invoke 代码运行良好,但我注意到他的目标是 .NET Framework 4 Client Profile。
如果我放置断点,那么它们会被命中并且一切都按预期工作,如果我以高于 4 的框架为目标,那么程序就会毫无例外地崩溃。
我在 C++ 中定义了一个非常简单的方法:framework.h
extern "C" {
API char* SayHello();
}
dllmain.cpp
char* SayHello() {
return (char*)"Hello";
}
C#
[DllImport("PInvokeTest.dll")]
public static extern string SayHello();
(我尝试在属性上设置 CallingConvention 和 CharSet 以不同的组合,我设法获得了汉字,但没有比框架 4 更高的工作)
我的 C++ 项目有 API=__declspec(dllexport) 它设置了预处理器定义,调用约定是 _stdcall (\Gz)(我也尝试过 _cdecl)。
C# 项目在 Framework 4 上运行良好,当我更改为高于此的任何内容时,它就会毫无例外地退出。
我还发现Dependencies GUI 向我表明SayHello 确实存在。
我们公司使用 4.6.1,我还遇到了 this article,它引导我到 PInvokeStackImbalance,但这对我来说没有任何作用。
任何帮助将不胜感激。
如果需要,我可以创建一个临时 GitHub 存储库。
【问题讨论】:
-
char*绝对不是C#的string。不确定它如何在任何情况下都能正常工作。您需要手动编写一个从 ASCII C 样式字符串到C#的字符串的包装器。 -
@ALX23z 感谢您的评论 - 如何将包装器从
char*写入字符串?正如我所说,我没有经验。谢谢 -
添加属性
[return: MarshalAs(UnmanagedType.LPStr)] -
啊,好的,谢谢 - 如果我知道这是一个字符串问题,那么我可能会做更多的研究