Skip to content

Latest commit

 

History

History
84 lines (67 loc) · 2.77 KB

File metadata and controls

84 lines (67 loc) · 2.77 KB

Interaction between Native and Managed Code for Arrays

Building upon the previous documentation, we now explore the interaction involving array data structures in both managed and native environments.

C# Class

ArrayFB1.cs

Arrays need to be handled as pointer and hand over as reference. They also always need to be [InOut] variables.

    ...
    [InOut]
    public Int32Array* IN_ARRAY;
    [InOut]
    public Int32Array* OUT_ARRAY;
    ...
    [Native]
    internal static class ArrayFB1NativeMethods
    {
        public static void Reverse(ref Int32Array outArray, ref Int32Array inArray)
        {
            // Implementation in native code
        }
    }

Native Implementation

ArrayFB1NativeMethods-cli.cpp

Again __PInvoke__ prefix is used to get to the managed method and write the native implementation.

void __PInvoke__ DocuSharedNativeLibrary::ArrayFB1NativeMethods::Reverse(DocuSharedNativeLibrary::Int32Array* p0, DocuSharedNativeLibrary::Int32Array* p1)
{
    Int32Array* outArray = p0;
    Int32Array* inArray = p1;

    if (inArray == 0 || outArray == 0)
    {
        return;
    }

    Int32* outData = &outArray->Anchor;
    Int32* inData = &inArray->Anchor;

    Int32 size = inArray->GetUpperBound() - inArray->GetLowerBound() + 1;
    for (int i = 0; i < size; i++)
    {
        Int32 value = inData[i];
        outData[size - i - 1] = value;
    }
}

C# Function Block

ArrayFB2.cs ArrayFB2-cli.cpp

It is the same for a function block with native implementation and arrays. In the native implementation file for ArrayFB2, the __Process method executes the core logic of manipulating the array. Just as with other methods, it is also prefixed with __PInvoke__ for smooth integration between managed and native code and the arrays need to be pointer.

void __PInvoke__ DocuSharedNativeLibrary::ArrayFB2::__Process()
{
    if (IN_ARRAY == 0 || OUT_ARRAY == 0)
    {
        return;
    }

    Int32* outData = &OUT_ARRAY->Anchor;
    Int32* inData = &IN_ARRAY->Anchor;

    Int32 size = IN_ARRAY->GetUpperBound() - IN_ARRAY->GetLowerBound() + 1;
    for (int i = 0; i < size; i++)
    {
        Int32 value = inData[i];
        outData[size - i - 1] = value; // Logic for reversing the input array
    }
}

Conclusion

In summary, the use of pointer variables is essential for handling arrays in the integration between managed and native code. Pointers facilitate direct access to the underlying data of arrays, allowing for efficient manipulation without the overhead of copying values. This mechanism not only enhances performance but also provides a flexible and powerful way to manage complex data structures across different layers of the application.