0

I want to use c++ code in my C# scripts for rendering some objects in unity 3d.

I have compiled the C++ script as a dll (lammps.dll) and have written a wrapper C# script to invoke a few functions from C++ script.

I am able to access void* and int* pointer successfully by doing the following:

Example:

  C++ prototype:
  void *lammps_extract_global(void *ptr, char *name);

  Equivalent C# prototype (in CSharpLibrary.cs file):

   DllImport("lammps.dll", EntryPoint = "lammps_extract_gloabl", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall);
   public static extern IntPtr lammps_extract_global(IntPtr ptr, [MarshalAs(UnmamanegType.LPStr)]String name);

Then I compile the C# file as a file which produces CSharpLibrary.dll

In another C# script I am using CSharpLibrary wrapper to access C++ functions as:

  1.  First define lmp_ptr as,
  var lmp_ptr = Marshal.AllocHGlobal(Marshal.Sizeof(typeof(System.IntPtr)));

  2.  Get lmp_ptr from C++ and dereference it as,
  var deref1 = (System.IntPtr)Marshal.PtrToStructure(lmp_ptr, typeof(System.IntPtr))

  3.  Then use deref1 to get natmPtr as, 
  System.IntPtr natmPtr = CSharpLibrary.CSharpLibrary.lammps_extract_global(deref1, "natoms");


   4. Convert natmPtr to an integer as,
    int nAtom = (int)Marshal.PtrToStructure(natmPtr, typeof(int))

Step 4 gives me appropriate value of nAtom.

I want to do the same thing as done for nAtom to another float pointer to pointer matrix storing positions.

   I did this to get the float pointer to pointer reference in C# 

Considering lammps_extract_atom has been defined similar to the function explain above, we have

   System.IntPtr posPtr = CSharpLibrary.CSharpLibrary.lammps_extract_atom(deref1, "x")

   Here posPtr is a float** value being returned from C++

Similar statement in C++ would have looked like

  float** posPtr = (double**)(lammps_extract_atom)(void *lmp_ptr, char *name)
Ankit Mishra
  • 409
  • 2
  • 5
  • 17
  • You want to return float array from C++ to C#? – Programmer Nov 26 '18 at 00:40
  • Yes I want to access the elements of float** array in C# – Ankit Mishra Nov 26 '18 at 00:42
  • 1
    Create the array in C# and update it in C++. See [this](https://stackoverflow.com/a/44424465/3785314) post. That's the most peformant way to do this. If you want to return Vector3, see [this](https://stackoverflow.com/a/53178114/3785314) post too. Not a good idea to return non Object pointer from C++. Again, this is due to performance (memory allocation. – Programmer Nov 26 '18 at 00:54
  • I cannot pass the C# array to C++ since the C++ code is quite complex and do not exactly know what is the entry point of initialization of the array. But I do know that the return value from the C++ function of interest is the desired value of interest. Thanks!! – Ankit Mishra Nov 26 '18 at 01:06
  • 1
    *"I cannot pass the C# array to C++ since the C++ code is quite complex"* That doesn't make any sense and yes, you can. I am not sure what you mean by entry point of initialization of the array but you can can pass C# array to C++ from the Awake or Start function to initialize the array if you actually read the post I linked. If you still decide to do it your own way, don't forget to free/delete it on the C++ side and also on the C# side. Goodluck! – Programmer Nov 26 '18 at 04:53
  • 1
    You can use function Marshal.PtrToStruct https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.ptrtostructure?view=netframework-3.5 – Liu Hao Nov 26 '18 at 09:42
  • 1
    @LiuHao Which requires `GCHandle.Alloc`, `GCHandle.Free` and freeing the array on the native just like programmer said. – PassetCronUs Nov 26 '18 at 21:42

0 Answers0