Click here to Skip to main content
15,905,420 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
I have a function to create a dll file with C++, this is:
XML
#include "stdafx.h"
#include <vector>
using namespace std;

void _stdcall fn(vector<double> &p, int* pLength)
{
    int i=0;
    double p_=0;
    do
    {
        p.push_back(p_);
        p_=2*p_+1;
        i++;
    }
    while (a condition of p_);    // The condition of loop....

    *pLength=i;

    return;
}


I compile it successfuly. (testFile.dll).
In C#, I call this function as follows:
C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("testFile.dll")]
        public static extern void fn(List<double> p, ref int pLength);
        static void Main(string[] args)
        {
            // I want to declare an array with unknown length (size),
            // because the length is calculated from fn() function!!!
            // And pass to fn() function to get p[i].....
            List<double> p = new List<double>();
            int pLength = 0;
            fn(p, ref pLength);

            // Display pLength and p[i]
            Console.WriteLine(pLength);
            for (int i = 0; i < pLength; i++)
                Console.WriteLine(p[i]);
            Console.ReadKey();
        }
    }
}


Build successfuly. When I run, I get an error:
C#
Cannot marshal 'parameter #1': Generic types cannot be marshaled.


at
C#
fn(p, ref pLength);



How to fix this error and to get correct result? Thanks.
Posted
Updated 1-Apr-14 0:59am
v5
Comments
[no name] 31-Mar-14 10:58am    
Why don't you just use an array like you did before?
Andrewpeter 31-Mar-14 11:04am    
Sorry, using array is not convenient! Because the array to pass for function is declared the unchanged size. I use List to improve that. What your idea about this? Thanks. It's difficult for me.

1 solution

C# List and C++ std::vector are not compatible. They are functionally equivalent but not binary compatible. To call native code from C#, you need data types that can be easily marshalled between managed and native code.

C++
#include "stdafx.h"
#include <vector>
using namespace std;
 
int _stdcall fn(double list[], int length)
{
    if (length < 20)
        return 0;

    double value = 0.f;
    for (int i = 0; i < 20; i++)
    {
        list[i] = value;
        value = value*2+1;
    }
    return 20;
}
</vector>


Import declared like so:

C#
[DllImport("testFile.dll")]
public static extern int fn(double[] list, int length);


Call the function from C# like so:

C#
double[] list = new double[20];
int length = 0;
length = fn(list, list.Length);


In this example, a return value of 0 means the list is too small.
 
Share this answer
 
v2
Comments
Andrewpeter 1-Apr-14 6:58am    
Sorry, I edit my code above! The condition (p_<20) is an example, in fact, it is an expression of p_. So I have to need to calculate pLength. That mean is: I dont know the size of p pointer in fn() function, when this function is finished we know this size (is pLength). You can help me complete this. Thanks.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900