c# - 将结构从非托管 C++ 传递到 C#

标签 c# c++ unmanaged

注意:最终的工作解决方案是在编辑之后!

我希望有人能帮助我解决过去几天我一直在努力解决的问题。

我正在尝试将结构从非托管 C++ DLL 传递到 C# 脚本。这是我目前所拥有的:

C++

EXPORT_API uchar *detectMarkers(...) {
    struct markerStruct {
            int id;
    } MarkerInfo;

    uchar *bytePtr = (uchar*) &MarkerInfo;

    ...

    MarkerInfo.id = 3;
    return bytePtr;
}

C#

[DllImport ("UnmanagedDll")] 
    public static extern byte[] detectMarkers(...);

...

[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 1)]
public struct markerStruct
{
    [MarshalAs(UnmanagedType.U4)]
    [FieldOffset(0)]
    public int Id;
}

...

markerStruct ByteArrayToNewStuff(byte[] bytes){
    GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    markerStruct stuff = (markerStruct)Marshal.PtrToStructure(
        handle.AddrOfPinnedObject(), typeof(markerStruct));
    handle.Free();
    return stuff;
}

...

print(ByteArrayToNewStuff (detectMarkers(d, W, H, d.Length) ).Id);

问题是这行得通,但打印的值完全不对(有时打印大约 400,有时打印最大 int 值)。

我猜我在 C# 中编码结构的方式有问题。有什么想法吗?

编辑:

这是使用 ref 的工作解决方案:

C++

struct markerStruct {
    int id;
};

...

EXPORT_API void detectMarkers( ... , markerStruct *MarkerInfo) {
    MarkerInfo->id = 3;
    return;
}

C#

[DllImport ("ArucoUnity")] 
    public static extern void detectMarkers( ... ,
        [MarshalAs(UnmanagedType.Struct)] ref MarkerStruct markerStruct);

...

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct MarkerStruct
{
    public int Id;
}

...

detectMarkers (d, W, H, d.Length, ref markerInfo);      
print( markerInfo.Id );

最佳答案

您正在返回一个指向局部变量的指针,该变量在 .NET 可以读取之前已被销毁。这在纯 C++ 中是个坏主意,在 p/invoke 中也是个坏主意。

相反,让 C# 传递一个指向结构的指针(只需使用 ref 关键字),C++ 代码只需填充它即可。

关于c# - 将结构从非托管 C++ 传递到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18519729/

相关文章:

C# 序列化一个带有 List 数据成员的类

c# - ASP.NET MVC 传递数据

c++ - 检测到堆损坏 : after Normal block(#151) at 0x00DB4E70

c++ - 使用 SND_MEMORY 在 PlaySound 中播放受控的音量级别

c++ - 我可以从 std::string 继承以提供强类型字符串吗?

c# - 调用 PInvoke 函数 '[...]' 使堆栈不平衡

c# - PCL DomCompiler 可移植类库输出

c# - 使用 POST 方法上传 JSON 对象时抛出 Bad Request Exception

c# - 可以从 C# 调用 C++ 代码吗?

涉及多个项目时的 C# 非托管导出 (Robert Giesecke)