如何使用返回向量的C ++ DLL

时间:2018-03-05 18:36:38

标签: c# c++

我有一个C ++ DLL,我试图在C#应用程序中使用它。 C ++ DLL返回包含多个矢量类型的对象。 C#抛出一个Method's type signature is not PInvoke compatible.

[StructLayout( LayoutKind.Sequential )]
public struct InputDLL
{
    public int a;
    public int b;
    public int c;
    public int d;
    public int e;
};


[StructLayout( LayoutKind.Sequential )]
public struct OutputDLL
{
    public List<int> vectorout;
};


public class TestVectorDLL
{
    [DllImport( "TestVectorDLL.dll",
        EntryPoint = "?RunDLL@@YA?AUOutputDLL@@UInputDLL@@@Z",
        CallingConvention = CallingConvention.Cdecl )]
    public static extern OutputDLL RunDLL( InputDLL input );
}

我编写了一个DLL,其唯一目的是测试包含向量的返回类型。 DLL将5个整数值作为输入,并以向量数据类型返回这5个整数。我使用DLL的代码是:

InputDLL input = new InputDLL()
{
    a = 1,
    b = 2,
    c = 3,
    d = 4,
    e = 5
};

OutputDLL output = TestVectorDLL.RunDLL(input);

以上一行会引发Method's type signature is not PInvoke compatible.

有人能指出我如何正确阅读C ++回归吗?

这是测试C ++ DLL的.h包括:

#pragma once  

#include <string>
#include <vector>
#include <array>

using namespace std;
#define  EPS_API __declspec(dllexport) 

struct InputDLL
{
    int a;
    int b;
    int c;
    int d;
    int e;
};

struct OutputDLL
{
    vector<int> vectorout;
};

EPS_API OutputDLL RunDLL(InputDLL Input);

1 个答案:

答案 0 :(得分:2)

在托管方法和本机方法之间传递参数时,您应该坚持使用可用的编组类型或实现自己的自定义编组器。 AFIK。 std:vector没有标准的编组器。您有两种选择:1。使用可用编组类型的更简单的实现(请参阅下面的代码)。 2.为std:vector实现ICustomMarshaller接口。您可以在此处找到此界面的说明: ICustomMarshaller interface

// A more modest marshalling example:
// C# code


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;

    namespace ConsoleApplication1
    {

        [StructLayout(LayoutKind.Sequential)]
        public struct input_struct
        {
            public int a;
            public int b;
            public int c;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct output_struct
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            public int[] o;
        }

        public class NativeVector
        {
            [DllImport("NativeVector.dll")]
            public static extern int RunDll(input_struct i, ref output_struct o);
        }

        class Program
        {
           static output_struct output = new output_struct();

            static void Main(string[] args)
            {
                input_struct input;
                input.a = 1;
                input.b = 2;
                input.c = 3;
                output.o = new int[3];
                NativeVector.RunDll(input, ref output);
            }
        }
    }


    // C++ code

    #include "stdafx.h"
    #include <vector>

    struct input
    {
        int a;
        int b;
        int c;
    };

    struct output
    {
        int v[3];
    };

    extern "C" 
    {
        __declspec(dllexport) int _stdcall  RunDll(struct input i, struct output& o)
        {
            o.v[0] = i.a;
            o.v[1] = i.b;
            o.v[2] = i.c;
            return 0;
        }
    }