Click here to Skip to main content
15,881,172 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Everybody,

I have converted a mfc vs6 application to vs2010.

My wish is to use managed code into a unmanaged c++ application. I have activated on the property page, the CLI extension feature.

Now come the query I would like to ask your inputs about:

In the unmanaged code, I have a:

C++
void UnmanagedFunction()
{
   float* pfValues = (float*) malloc(20 * sizeof(float));

   pfValues[0..19] = random value.

   CNetHelper^ Helper = gcnew CNetHelper();

   int iSize = Marshal.SizeOf(typeof(float)) * 20;

   IntPtr ptrValues = = Marshal.AllocHGlobal(iSize);

   Marshal.Copy(pfValues, 0, ptrValues , 20);

   Helper->HelpMethod(ptrValues);

   Marshal.FreeHGlobal(ptrValues); 

}

in c#
C#
public class CNetHelper
{
  public void HelpMethod(IntPtr ptrValues)
  {
   // retrieve the samples
   // I will mange it via Block.Copy
  }
}


XML
The problem:
pfValues cannot be converted from float* to float[]
How should I proceed to copy the float array via pfValues into IntPtr to pass it then to csharp method ? 


Thank you very much in advance.
Best regards.
MiQi.
Posted
Comments
Philippe Mori 14-Nov-13 19:35pm    
What it the purpose of all that ugly code. C++/CLI can uses managed code so you would usually make the transition between native/unsafe code and managed/safe code on C++/CLI side.

There are no reason to do such code as that. On C# side use float[] and in C++/CLI you can call directly that method. Something like:

C# side:
C#
public class CNetHelper
{
  public void HelpMethod(float[] values)
  {
   // You work there as you always do in C#
  }
}


C++/CLI side:
C++
void CppCliFunction()
{
   cli::array<float> ^values = gcnew cli::array<float>(20);

   // Fill array with random values...
   for (int i = 0; i != values->Length; ++i)
   {
      values[i] = random value.
   }

   CNetHelper^ Helper = gcnew CNetHelper();
 
   Helper->HelpMethod(values);
}
 
Share this answer
 
v4
Comments
Ron Beyer 14-Nov-13 21:01pm    
Even better! +5
SuperMiQi 15-Nov-13 8:21am    
Thank you very much, it works well.
Well there is one not-so-obvious solution...

In the C# program, add this as another "help method":

C#
public unsafe float[] GetFloatArray(float* floats, int count)
{
    float[] retVal = new float[count];

    for (int i = 0; i < count; i++)
    {
        retVal[i++] = *floats;
        floats++;
    }

    return retVal;
}


Its not obvious because most people don't realize that .NET happily works with pointer types just like C++. You will have to compile the program with the "unsafe" flag set (Properties->Build->Allow unsafe code, or /unsafe from the command line).

Now I haven't tried the above code so there may be tweaks you have to do, but the concept is there, you can convert from a floating point pointer and a length to a float array.
 
Share this answer
 
Comments
SuperMiQi 14-Nov-13 17:00pm    
Hello Ron,

Thank you.
May I apply a block.copy to avoid to use a for loop ietration ?

Thank you.
Best regards.
MiQi.
Ron Beyer 14-Nov-13 17:12pm    
I don't think so, but the loop is not inefficient (especially with the use of pointers), so I wouldn't worry about performance in that regard.
SuperMiQi 14-Nov-13 17:35pm    
Hello Ron,
Ok.
For you this is the only solution to cover that issue ?
Nothing can be applied in the c++/cli code part ?

Thank you in advance.
Best regards.
MiQi
Ron Beyer 14-Nov-13 17:40pm    
You may able to copy it into a System.Array and pass that to the function, it may require a little playing around with.
Philippe Mori 14-Nov-13 19:28pm    
I don't see why you would make C# code unsafe instead of doing C++/CLI code safe. See also my solution. Maybe if you already have the data on that format on C++ side...

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