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

Posted

技术标签:

【中文标题】如何使用返回向量的 C++ DLL【英文标题】:How to use C++ DLL that returns vector 【发布时间】:2018-03-05 18:36:37 【问题描述】:

我有一个 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);

【问题讨论】:

发布 C++ 签名。 @Aybe 我编辑了我的问题以包含 .h - 这是您要查找的内容吗? 编组 C++ 类是一件头疼的事。您可以尝试遵循以下建议:***.com/a/16003004/2819245。但可能更好的选择是在不使用 C++ 类型的情况下设计 DLL 导出,或者在 C++/CLI 中编写额外的混合程序集(在其中您可以轻松地或多或少地直接将向量转换为所需的任何 .NET 类型) 让我领先几秒钟,这就是我要建议的! How to return a list in C# using P/Invoke?的可能重复 【参考方案1】:

在托管方法和本机方法之间传递参数时,您应该坚持使用可用的编组类型或实现您自己的自定义编组器。阿菲克。 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;
        
    

【讨论】:

“更谦虚”的方法可以适应我们的需要。谢谢维克多。

以上是关于如何使用返回向量的 C++ DLL的主要内容,如果未能解决你的问题,请参考以下文章

如何在 DLL 中返回向量?

如何将 C# 中的二维数组传递给 C++ DLL?

如何在 Java 代码中使用从 .dll 使用和返回对象的函数?

C++ 如何制作二维向量函数?

从 python ctypes 中的 c++ dll 传递向量

如何在 C++ 中通过引用返回向量