将结构从VC ++返回到C#

问题描述 投票:1回答:2

我在VC ++中编写了一个结构。我已经制作了一个VC ++代码的DLL并使用PInvoke在C#中调用了这个dll。

VC ++ dll看起来像这样

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#if defined(_MSC_VER)
#include <windows.h>
#define DLL extern "C" __declspec(dllexport)
#else
#define DLL
#endif


struct SYSTEM_OUTPUT
{
    int status;
};


DLL SYSTEM_OUTPUT* getStatus()
{
    SYSTEM_OUTPUT* output;
    output->status = 7;

    return output;
}

我在我的C#代码中从dll调用getStatus()函数,如下所示;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace UsingReturnStructDLL
{
    [StructLayout(LayoutKind.Sequential)]
    public struct SYSTEM_OUTPUT
    {
        [MarshalAs(UnmanagedType.I4)]
        int Status;
    }



public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

        public SYSTEM_OUTPUT output;

        [DllImport("ReturnStructDLL", EntryPoint = "getStatus")]
        [return: MarshalAs(UnmanagedType.Struct)]
        public extern static SYSTEM_OUTPUT getStatus();



        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                SYSTEM_OUTPUT output = getStatus();
            }
            catch (AccessViolationException e)
            {
                label1.Text = e.Message;
            }

        }
    }
}

我想在我的C#代码中检索结构中的值。通过上面的代码设置,我收到以下错误;

Cannot marshal 'return value': Invalid managed/unmanaged type combination (Int32/UInt32
must be paired with I4, U4, or Error).

有人可以帮我解决这个问题吗?

谢谢。

c# visual-c++ dll pinvoke marshalling
2个回答
3
投票

使您的C ++代码首先运行。它是已发布的垃圾,您不会初始化指针。它会因AccessViolation而崩溃。

返回指向结构的指针很难在C / C ++中正确使用,代码的客户端将不知道如何释放内存。这也会对P / Invoke marshaller造成严重破坏,它将尝试使用CoTaskMemFree()释放指针。这是Vista上的一个kaboom,XP上的内存泄漏。

如果让客户端将指向结构的指针作为参数传递,则所有这些问题都会消失:

void getStatus(SYSTEM_OUTPUT* buffer)

然后在C#中成为:

[DllImport("mumble.dll")]
private static extern void getStatus(out SYSTEM_OUTPUT buffer);

-1
投票
struct SYSTEM_OUTPUT
{
    int status; // try change to long
};
© www.soinside.com 2019 - 2024. All rights reserved.