【问题标题】:P/Invoke and .NET Target Framework [duplicate]P/Invoke 和 .NET Target Framework [重复]
【发布时间】: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)]
  • 啊,好的,谢谢 - 如果我知道这是一个字符串问题,那么我可能会做更多的研究

标签: c# c++ pinvoke


【解决方案1】:

现在我知道这是一个字符串问题,我做了一些搜索,发现this SO question
所以最后我使用了BSTR的方法。

BSTR SayHello() {
    return ::SysAllocString(L"Hello");
}
        [DllImport("DBReplicator.Lib.dll")]
        [return: MarshalAs(UnmanagedType.BStr)]
        public static extern string SayHello();

...不过我还是不知道我是怎么弄到汉字的。

【讨论】:

  • BSTR 支持完整的 Unicode 范围。
  • 前段时间,我为 .NET 和 .NET Framework 准备了一个关于在 C/C++ 和 C# 之间编组字符串的完整示例解决方案......这些示例完全没有文档记录,但非常完整。你可以看看github.com/xanatos/CSharpCPlusPlusInteropSamples
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多