0

I need to pass an array from C++ to C#

The C++ header is the following

extern "C" GMSH_API void GMSH_Model_OCC_Fragments(int* arrayPtr);

The C++ cpp is the following

void GMSH_Model_OCC_Fragments(int* arrayPtr)
{
    int array[] = {1,2};
    arrayPtr = array;
}

The C# code is the following

[DllImport("GMSHCSHARP.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GMSH_Model_OCC_Fragments(out IntPtr arrayPtr);     
    
public void Create()
{
    GMSH_Model_OCC_Fragments(out IntPtr arrayPtr);
    int[] ReturnArray = new int[2];
    int size = Marshal.SizeOf(ReturnArray[0]) * ReturnArray.Length;
    Marshal.Copy(arrayPtr, ReturnArray, 0, size);
}

Seems that arrayPtr is transmitted as null and this causes the Marshal.Copy to return an error.

I'd appreciate any help.

3
  • 1
    Your C++ code is not valid. You cannot return the address of a stack variable. The result of that is undefined. Commented Jul 10, 2022 at 8:07
  • I'm very new to C++, although I have extensive C# experience. Commented Jul 10, 2022 at 8:10
  • What exact error are you getting? And maybe you should explain what you're trying to do. Unless you have to work with an existing C++ library, it is barely necessary to write a library in C++ when you actually want to use C#. Commented Jul 10, 2022 at 8:12

1 Answer 1

1

When you call C++ from C# you have to play by the rules of C++, so you cannot assign an array by

arrayPtr = array;

You can however fill an array given by C#

C++ Function

void someFunction(char* dest, size_t length){
     char* someData = "helloWorld";
     size_t copyLen = std::min(length, strlen(someData));

     memcpy(dest, someData, copyLen);
     //If it was a string you'd also want to make sure it's null terminated
}

C# Function call (Something like this sorry if it's not 100%)

[DllImport("MyDll.dll", CallingConvention = CallingConvention.CDecl)]
private static extern void someFunction(Byte[] dest, uint Length);

Byte[] array = new byte[10];
someFunction(array, 10);

I'm not sure if you can pass heap memory out of C++, but if you can you would do this:

void GMSH_Model_OCC_Fragments(int** dest){
     *dest = new int[2];
     *dest[0] = 1;
     *dest[1] = 2;
}

Note you need to use a double pointer to pass back memory in this fashion. As you need the first pointer to reference the object or array, and the second pointer to keep track of that.

Sign up to request clarification or add additional context in comments.

2 Comments

You can pass heap memory out, but you would need to pass the pointer back in order to destroy it, so bad idea. Much better to just pass in a buffer from C# as you suggest
@Justin The first part of the answer was really helpful. Unfortunately, with my current level of knowledge I wasn't able to understand the double pointers. Thanks anyway!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.