Passing an int array from C # to native code using interop

I have Blah.cs:

public unsafe static int Main()
{
  int[] ai = {1, 2, 3, 4, 5};
  UIntPtr stai = (UIntPtr) ai.Length;
  CManagedStuff obj = new CManagedStuff();
  obj.DoSomething(ai, stai);
}

Then ManagedStuff.cpp:

void CManagedStuff::DoSomething(int^ _ai, UIntPtr _stai)
{
  // Here I should do something to marshal the int^ to an int*
  pUnmanagedStuff->DoSomething(_ai, (size_t) _stai);
}

And UnmanagedStuff.cpp:

void CUnmanagedStuff::DoSomething(int* _ai, size_t _stai)
{
  // Walk and print the _stai ints in _ai
}

How to transfer int[] aifrom Main to ManagedStuff :: DoSomething? I understand that there is no marshaling in this call because all managed code is managed.

And how can I then marshal int^ _aiin ManagedStuff :: DoSomething to call UnmanagedStuff :: DoSomething? If I had int[] _ai, then the code in the answer for this SO question could help ( C #: Marshalling a "pointer to an array of int" from SendMessage () lParam ).

Alternatively, how can I avoid working with C #, C ++ - interaction, Microsoft and Windows and stop the suffering of the world?

+3
source share
3

, :

void CManagedStuff::DoSomething(array<int>^ _ai, UIntPtr _stai)
{
  // Here I should do something to marshal the int^ to an int*
  pin_ptr<int> _aiPinned = &_ai[0];
  pUnmanagedStuff->DoSomething(_aiPinned, (size_t) _stai);
}

array<int>^.
-, , -, .

+1

, .

, , .

, int^ , . , .

, . .

+2

You must bind the managed resource (your array) so that the garbage collector does not move it while you use the pointer.

In C #, you can do this with a statement fixed: fixed Statement (C # link)

C ++ bindings work with pinning pointers that bind a managed entity while they are in scope. (A pointer to any element will bind the entire array):

// In CManagedStuff:
pin_ptr<int> _aiPinned = _ai

Additional info: C ++ / CLI in action - using internal and pinning pointers

+1
source

All Articles