Abhishek
Abhishek

Reputation: 2945

Setting variables in C++ through C# structure

I have a solution with 3 projects. A C# WinForms project which depends on second project which is a C++ DLL. The C++ DLL depends on the third project which is a static library. The static library is C code with C++ classes. The DLL acts as an interop between the C code and C# code.

I need to set the variables used by the static library through C# structure.

I do not have experience in C++/CLI (I have started reading. Examples found on the web do not make sense to me as of now)

So far, I have created a structure in C#. I created a initialized unmanaged memory to hold this struct:

IntPtr ptData = Marshal.AllocHGlobal(Marshal.SizeOf(objMyClass.data));//data is the structure I am initializing in the constructor of MyClass
Marshal.StructureToPtr(objPythonInterop.data, ptData, false);
objCPPClass.UpdateData(ptData);//objCPPClass is object to class in DLL. libClass is the object of class in static library

This is my structure in C#:

[StructLayout(LayoutKind.Sequential)]
public struct Data
{
    members here..
}

In the DLL, this is the UpdateData function:

Header:

void UpdateData(IntPtr ptrData);

Source:

void CPPClass::UpdateData(IntPtr ptrData)
{
    m_lib->UpdateDataInLib(ptrData);// m_lib is object to class in static library
}

UpdateDataInLib is a function in the Class in Static library. How do I use the ptrData in this function and update the variables? I have a structure in the static library similar to the structure defined in my C# code. How do I cast the ptr to this structure and access the members?

I have a structure in my C++ static library which contains equivalent members of the structure in C#:

extern "C"  __declspec(dllexport) typedef struct Data
{
    members here..
}Data, *pData;

I need help.

Upvotes: 0

Views: 333

Answers (1)

Lucas Trzesniewski
Lucas Trzesniewski

Reputation: 51330

There's a simpler approach. You don't need dynamic memory allocation if your DLL doesn't access the structure anymore after the call. Just put the structure on the stack (you still need fixed nevertheless):

var data = new objMyClass.data
{
    field1 = value1, // etc
};

unsafe
{
    fixed (objMyClass.data* ptr = &data)
    {
        objCPPClass.UpdateData(new IntPtr(ptr));
    }
}

If the structure is long-lived then keep your code as-is but don't forget to free the allocated memory.

Then, on the C++ side, you could just cast:

void CPPClass::UpdateData(IntPtr ptrData)
{
    m_lib->UpdateDataInLib(static_cast<pData>(ptrData.ToPointer()));
}

But as I don't know the signature of UpdateDataInLib I'm not sure about this approach.

Also, you can get rid of the IntPtr intermediate step, and just use a pointer.

Upvotes: 1

Related Questions