skip to Main Content

I am new to C# and visual studio. I have wrote one function in C++.
I need to encapsulate C++ functions into dynamic link libraries(DLL),and then using C# to call C++ to operate vector data n parameters.


Here is my main function.

#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;
}

And here is my .h file:

#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

Here is my calling function "ConsoleApp1" for DLL files:
Now I compiled the code to DLL using newest Cmake and VS2022.I want to input the parameters(double length,std::vectorlength_par), and get the result in C#( std::vector &length_final, std::vectorstd::vector<int> &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);

        }

    }
}

I tried to write a correct call file that was feasible when running a function without input and output parameters, but when I added parameters to the function, I failed. I have tried many ways to write call function,so my code is a bit confusing, and even my ideas are completely incorrect,I sincerely hope to receive your suggestions and corrections!Thank u!

2

Answers


  1. It appears that you want to call a C++ function from a DLL in C# with certain input and output parameters. To do this, you need to make sure your C++ code is properly wrapped in a DLL and the C# code is correctly set up to call it.

    C++ Code: Your C++ code appears to be almost correct, but there are a few issues. In your function declaration and definition, the data types of length_par, length_final, and bb_vec don’t match in C++ and C#. You should use arrays for length_par and length_final in C++, as follows:

    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# Code: Your C# code also needs some adjustments:

    Create appropriate managed structures that match the C++ parameters.
    Use MarshalAs attributes to ensure data is marshaled correctly.
    Make sure to use IntPtr for arrays to correctly marshal them to C++.
    Here’s an example of how your C# code should look:

    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.
            }
        }
    }
    

    Memory Management: In C#, you should allocate memory for the bb_vec elements before calling cal_lenth and then free the memory after you’re done with the data to prevent memory leaks.
    This code should help you call your C++ function from C#. Please ensure that you’ve properly compiled your C++ code into a DLL and that the DLL is accessible from your C# project.

    Hope this is the solution you were looking for!

    Login or Signup to reply.
  2. As the comments said, avoid using standard library types across the .net boundary.
    Considering dynamic arrays are required and your example does not have specific C++ third party library, it will be more convenient to use C# code. Such as :

       static void CalLength(double length, List<int> lengthPar, List<int> lengthFinal, List<List<int>> bbVec)
        {
            for (int i = 0; i < lengthPar.Count; i++)
            {
                lengthFinal[i] = lengthPar[i];
                Console.WriteLine(lengthFinal[i]);
            }
            Console.WriteLine();
    
            for (int i = 0; i < 5; i++)
            {
                bbVec.Add(new List<int>(lengthPar));
            }
    
            Console.WriteLine("endend");
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search