如何将向量数据从c#传递到C++以及从C++获取向量数据到c#?

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

我是 C# 和 Visual Studio 的新手。我用 C++ 写了一个函数。 我需要将C++函数封装成动态链接库(DLL),然后用C#调用C++操作向量数据n个参数。


这是我的主要功能。

#include "pch.h"
#include <time.h>
#include <vector>
#include<iostream>
Void cal_lenth(double length,std::vector<int>length_par, std::vector<int> &length_final, std::vector<std::vector<int>> &bb_vec){
   //int length=100;
   //std::vector<int> length_par = {5,6,7,8,9};
   for (int i = 0; i < length_par.size(); i++) {
       length_final[i]=length_par[i];
       std::cout<<length_final[i];
       }
      std::cout<<std::endl;
   }
std::vector<std::vector<int>> bb;
   for (int i = 0; i < 5; i++) {
    bb_vec.push_back(length_par);
   }
   std::cout<<"endend"<<std::endl;
}

这是我的 .h 文件:

#define IMPORT_DLL extern "C" _declspec(dllimport)
#ifndef PCH_H
#define PCH_H
#include <cstdlib>
#include <string>
#include <numeric>
#include <time.h>
using namespace std;
IMPORT_DLL void cal_lenth(double length,std::vector<int>length_par, std::vector<int> &length_final, std::vector<std::vector<int>> &bb_vec);
#endif //PCH_H

这是我对 DLL 文件的调用函数“ConsoleApp1”: 现在我使用最新的Cmake和VS2022将代码编译为DLL。我想输入参数(double length,std::vectorlength_par),并在C#中得到结果(std::vector &length_final, std::vectorstd::vector &bb).

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using static ConsoleApp1.Program;

namespace ConsoleApp1
{
    internal class Program
    {
        private double length;
        public class Vector
        {
            //private double length;
            private double[] length_par;
            public int Length_len => length_par.Length;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct Length_par
        {
            public double length;
            //public Vector length_par = new double Vector();
            public double a;
            public double b;
            public double c;
        }
        [DllImport("pch.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void cal_lenth(ref double length, ref Vector length_par,ref Vector &length_final,ref Vector &bb_vec);
        Length_par length_par = new Length_par();
        length_par.Add (1); //wrong
         
            
        //int result = cal_lenth(length_par);
        static void Main()
        {
            double length  = 100;
            //Vector length_par = new Vector();
            //length_par.a = 1;
            Vector num_par = new Vector();
            cal_lenth(ref length, ref length_par,out length_final,out Vector &bb_vec);

        }

    }
}

我尝试编写一个正确的调用文件,该文件在运行没有输入和输出参数的函数时是可行的,但是当我向函数添加参数时,我失败了。我尝试了很多方法来编写调用函数,所以我的代码有点混乱,甚至我的想法完全不正确,我真诚地希望收到您的建议和指正!谢谢您!

c# c++ visual-studio vector dll
1个回答
0
投票

您似乎想使用某些输入和输出参数从 C# 中的 DLL 调用 C++ 函数。为此,您需要确保 C++ 代码正确包装在 DLL 中,并且 C# 代码正确设置为调用它。

C++ 代码:您的 C++ 代码看起来几乎是正确的,但存在一些问题。在函数声明和定义中,length_par、length_final 和 bb_vec 的数据类型在 C++ 和 C# 中不匹配。在 C++ 中,您应该使用数组作为 length_par 和 length_final,如下所示:

IMPORT_DLL void cal_lenth(double length, int* length_par, int length_par_size, int* length_final, int length_final_size, int** bb_vec, int bb_vec_size);

C# 代码:您的 C# 代码还需要一些调整:

创建与 C++ 参数匹配的适当托管结构。 使用 MarshalAs 属性确保数据正确编组。 确保对数组使用 IntPtr 以将它们正确封送至 C++。 以下是 C# 代码的外观示例:

using System;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    internal class Program
    {
        [DllImport("pch.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void cal_lenth(
            double length,
            [In, MarshalAs(UnmanagedType.LPArray)] int[] length_par,
            int length_par_size,
            [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] length_final,
            int length_final_size,
            [In, Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] bb_vec,
            int bb_vec_size
        );

        static void Main()
        {
            double length = 100;
            int[] length_par = new int[] { 5, 6, 7, 8, 9 };
            int[] length_final = new int[length_par.Length];
            IntPtr[] bb_vec = new IntPtr[5]; // Assuming you want an array of arrays

            cal_lenth(length, length_par, length_par.Length, length_final, length_final.Length, bb_vec, bb_vec.Length);

            // Now, you can work with 'length_final' and 'bb_vec' in C#
            // Don't forget to clean up memory if necessary.
        }
    }
}

内存管理:在 C# 中,您应该在调用 cal_lenth 之前为 bb_vec 元素分配内存,然后在处理完数据后释放内存,以防止内存泄漏。 此代码应该可以帮助您从 C# 调用 C++ 函数。请确保您已将 C++ 代码正确编译为 DLL,并且可以从 C# 项目访问该 DLL。

希望这是您正在寻找的解决方案!

© www.soinside.com 2019 - 2024. All rights reserved.