C# C++ 互操作:C++向C#输出不定长数组或指针的实现

这种需求算有点难度吧,在这里贴出一个实现以供参考:

C++部分:头文件

// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 CALCULATE_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// CALCULATE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。

#ifndef _Calculate_
#define _Calculate_

#include <stdlib.h>

#ifdef CALCULATE_EXPORTS
#define CALCULATE_API extern "C" __declspec(dllexport)
#else
#define CALCULATE_API __declspec(dllimport)
#endif


typedef intptr_t  IntPtr;

CALCULATE_API int MultiGray(
    double st_high,
    double st_low,

    IntPtr* P_inflect_handle,
    int** P_inflect,
    int* P_inflect_Len,

    double set_max,
    double set_min,
    double response_setTime,

    IntPtr* P_mid_handle,
    int** P_mid,
    int* P_mid_Len,

    IntPtr* flag_handle,
    int** flag,
    int* flag_Len,

    int jump_edge,
    int tcon_OD_up,
    int tcon_OD_down,

    IntPtr* P_left_handle,
    int** P_left,
    int* P_left_Len,

    IntPtr* P_right_handle,
    int** P_right,
    int* P_right_Len,
    int freq,
    double response
);
CALCULATE_API bool ReleaseObject(IntPtr handle);

#endif

C++部分:函数实现

// Calculate.cpp : 定义 DLL 的导出函数。
//


#include "pch.h"
#include "framework.h"
#include "Calculate.h"
#include <vector>
using namespace std;

CALCULATE_API int MultiGray(
    double st_high,
    double st_low,

    IntPtr* P_inflect_handle,
    int** P_inflect,
    int* P_inflect_Len,

    double set_max,
    double set_min,
    double response_setTime,

    IntPtr* P_mid_handle,
    int** P_mid,
    int* P_mid_Len,

    IntPtr* flag_handle,
    int** flag,
    int* flag_Len,

    int jump_edge,
    int tcon_OD_up,
    int tcon_OD_down,

    IntPtr* P_left_handle,
    int** P_left,
    int* P_left_Len,

    IntPtr* P_right_handle,
    int** P_right,
    int* P_right_Len,
    int freq,
    double response
)
{
    int count = 100000;
    auto array1 = new std::vector<int>();
    for (int i = 0; i < count; i++)
    {
        array1->push_back(i);
    }
    *P_inflect_handle = reinterpret_cast<IntPtr>(array1);
    *P_inflect = array1->data();
    *P_inflect_Len = count;

    auto array2 = new std::vector<int>();
    for (int i = 0; i < count; i++)
    {
        array2->push_back(i);
    }
    *P_mid_handle = reinterpret_cast<IntPtr>(array2);
    *P_mid = array2->data();
    *P_mid_Len = count;


    auto array3 = new std::vector<int>();
    for (int i = 0; i < count; i++)
    {
        array3->push_back(i);
    }
    *flag_handle = reinterpret_cast<IntPtr>(array3);
    *flag = array3->data();
    *flag_Len = count;

    auto array4 = new std::vector<int>();
    for (int i = 0; i < count; i++)
    {
        array4->push_back(i);
    }
    *P_left_handle = reinterpret_cast<IntPtr>(array4);
    *P_left = array4->data();
    *P_left_Len = count;

    auto array5 = new std::vector<int>();
    for (int i = 0; i < count; i++)
    {
        array5->push_back(i);
    }
    *P_right_handle = reinterpret_cast<IntPtr>(array5);
    *P_right = array5->data();
    *P_right_Len = count;

    return 0;
}


CALCULATE_API bool ReleaseObject(IntPtr handle)
{
    std::vector<int>* object = reinterpret_cast<std::vector<int>*>(handle);
    delete object;
    return true;
}

C# 部分:

 public class SafeHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        public SafeHandle()
            : base(true)
        {
        }
        protected override bool ReleaseHandle()
        {
            return ReleaseObject(handle);
        }

        [DllImport("Calculate.dll", CallingConvention = CallingConvention.Cdecl)]
        static unsafe extern bool ReleaseObject(IntPtr handle);
    }
 public class Performer
    {
        [DllImport("Calculate.dll", EntryPoint = "MultiGray", CallingConvention = CallingConvention.Cdecl)]

         unsafe extern static int MultiGray(
   double st_high,
   double st_low,

   out SafeHandle handle1,
   out int* P_inflect,
   out int P_inflect_Len,

   double set_max,
   double set_min,
   double response_setTime,

   out SafeHandle handle2,
   out int* P_mid,
   out int P_mid_Len,

   out SafeHandle handle3,
   out int* flag,
   out int flag_Len,

   int jump_edge,
   int tcon_OD_up,
   int tcon_OD_down,

   out SafeHandle handle4,
   out int* P_left,
   out int P_left_Len,

   out SafeHandle handle5,
   out int* P_right,
   out int P_right_Len,
   int freq,
   double response
           );
        public unsafe ReturnData Excute(

           double st_high,
   double st_low,

   out SafeHandle handle1,
   out int* P_inflect,
   out int P_inflect_Len,

   double set_max,
   double set_min,
   double response_setTime,

   out SafeHandle handle2,
   out int* P_mid,
   out int P_mid_Len,

   out SafeHandle handle3,
   out int* flag,
   out int flag_Len,

   int jump_edge,
   int tcon_OD_up,
   int tcon_OD_down,

   out SafeHandle handle4,
   out int* P_left,
   out int P_left_Len,

   out SafeHandle handle5,
   out int* P_right,
   out int P_right_Len,
   int freq,
   double response
           )
        {
            int result = MultiGray(
                 st_high,
                 st_low,
                 out handle1,
                 out P_inflect,
                 out P_inflect_Len,
                 set_max,
                 set_min,
                 response_setTime,
                 out handle2,
                 out P_mid,
                 out P_mid_Len,
                 out handle3,
                 out flag,
                 out flag_Len,
                 jump_edge,
                 tcon_OD_up,
                 tcon_OD_down,
                 out handle4,
                 out P_left,
                 out P_left_Len,
                 out handle5,
                 out P_right,
                 out P_right_Len,
                 freq,
                 response
                 );
            ReturnData data = new ReturnData();
            data.flag_Len = flag_Len;
            data.flag = new int[flag_Len];
            for(int i=0;i<flag_Len;i++)
            {
                data.flag[i] = flag[i];
            }
            data.freq = freq;
            data.jump_edge = jump_edge;
            data.P_inflect_Len = P_inflect_Len;
            data.P_inflect = new int[P_inflect_Len];
            for(int i=0;i<P_inflect_Len;i++)
            {
                data.P_inflect[i] = P_inflect[i];
            }
            data.P_left_Len = P_left_Len;
            data.P_left = new int[P_left_Len];
            for(int i=0;i<P_left_Len;i++)
            {
                data.P_left[i] = P_left[i];
            }
            data.P_mid_Len = P_mid_Len;
            data.P_mid = new int[P_mid_Len];
            for(int i=0;i<P_mid_Len;i++)
            {
                data.P_mid[i] = P_mid[i];
            }
            data.P_right_Len = P_right_Len;
            data.P_right = new int[P_right_Len];
            for(int i=0;i<P_right_Len;i++)
            {
                data.P_right[i] = P_right[i];
            }
            data.response = response;
            data.response_setTime = response_setTime;
            data.set_max = set_max;
            data.set_min = set_min;
            data.st_high = st_high;
            data.st_low = st_low;
            data.tcon_OD_down = tcon_OD_down;
            data.tcon_OD_up = tcon_OD_up;

            handle1.Dispose();
            handle2.Dispose();
            handle3.Dispose();
            handle4.Dispose();
            handle5.Dispose();

            return data;
            
        }
    }

public class ReturnData
    {
        public double st_high;
        public double st_low;

        public int[] P_inflect;
        public int P_inflect_Len;

        public double set_max;
        public double set_min;
        public double response_setTime;

        public int[] P_mid;
        public int P_mid_Len;

        public int[] flag;
        public int flag_Len;

        public int jump_edge;
        public int tcon_OD_up;
        public int tcon_OD_down;

        public int[] P_left;
        public int P_left_Len;

        public int[] P_right;
        public int P_right_Len;
        public int freq;
        public double response;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值