【问题标题】:P/Invoke Calls FailingP/Invoke 调用失败
【发布时间】:2014-02-24 12:59:57
【问题描述】:

我在 C++ 中定义了以下结构:

struct GraphicsAdapterDesc {
    // ... Just some constructors / operators / destructor here
    DEFINE_DEFAULT_CONSTRUCTOR(GraphicsAdapterDesc);
    DEFINE_DEFAULT_DESTRUCTOR(GraphicsAdapterDesc);
    ALLOW_COPY_ASSIGN_MOVE(GraphicsAdapterDesc);

    std::wstring AdapterName;
    int32_t AdapterNum;
    std::wstring HardwareHash;

    int64_t DedicatedVMEM;
    int64_t DedicatedSMEM;
    int64_t SharedSMEM;

    int32_t NumOutputs;
};

在 C# 中,我有一个这样声明的“镜像”结构:

[StructLayout(LayoutKind.Sequential)]
public struct GraphicsAdapterDesc {
    string AdapterName;
    int AdapterNum;
    string HardwareHash;

    long DedicatedVMEM;
    long DedicatedSMEM;
    long SharedSMEM;

    int NumOutputs;
};

我尝试非常小心地匹配变量的宽度(尽管我有点不确定如何准确地处理字符串)。

无论如何,我有以下导出的 C 方法:

extern "C" __declspec(dllexport) bool GetGraphicsAdapter(int32_t adapterIndex, GraphicsAdapterDesc& outAdapterDesc) {
    outAdapterDesc = RENDER_COMPONENT.GetGraphicsAdapter(adapterIndex);
    return true;
}

并且,我的 C# 应用程序中的以下 extern 方法:

[DllImport(InteropUtils.RUNTIME_DLL, EntryPoint = "GetGraphicsAdapter", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool _GetGraphicsAdapter(int adapterIndex, out GraphicsAdapterDesc adapterDesc);

但是,当我调用它时,它无法正常工作。根据我是在 x64 还是 x86 模式下编译(C++ DLL 和 C# 应用程序都编译为 x86 或 x64),我得到不同的结果:

  • 在 x86 模式下,调用返回,但结构中包含“废话”值,并且字符串均为空,
  • 在 x64 模式下,调用会引发 NullPointerException。

我的期望是我在编组字符串时做错了,我需要为字符指定“宽模式”,但我不知道如何(或者这是否是正确的选择)。

提前谢谢你。

【问题讨论】:

    标签: c# c++ struct pinvoke


    【解决方案1】:

    C++ 类型与 C# 不兼容,除非它们封装在托管 C++ 中。并且您使用的 std::wstring 无法编组到 .NET。

    要成功进行互操作,您需要使用 wchar_t[]whar_t* 并告诉 C# 现在对其进行编组。

    【讨论】:

      【解决方案2】:

      我不知道你的宏在做什么,但这只有在你的 c++ 类型是POD 时才有效。 c++11 对 POD 有扩展的意义,但我认为你无论如何都不符合扩展的标准。否则你不能保证布局。如果你想将你的 c++ 类导出到 C#,我建议你使用 c++\cli。此外,您在 stuct 中定义了 wstring,它们绝对不是 POD。当您使用 DLLImport 时,请仅考虑 C 构造,否则您将度过一段糟糕的时光。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-02
        • 2010-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 2016-07-15
        相关资源
        最近更新 更多