3

I'm calling functions from C++ that returns a pointer to an array of struct and I'm having problems since I'm new to this operation/implementation.

My C++ codes:

// My C++ Structs typedef struct _MainData { double dCount; DataS1 *DS1; int iCount1; DataS2 *DS2; int iCount2; }MainData; typedef struct _DataS1 { unsigned int uiCount1; unsigned int uiCount2; int iCount; void *pA; void *pB; } DataS1; typedef struct _DataS2 { unsigned int uiCount1; unsigned int uiCount2; unsigned int uiCount3; unsigned int uiCount4; double dCount; int iCount1; char strLbl[64]; } DataS2; // My C++ Function MainData* GetData(const int ID) { MainData* mData; int iLength = Get_Count(); mData = new MainData[iLength]; for(int x = 0;x < VarCounter; x++) { // Codes here assign data to mData[x] } return mData; } 

Question: How can I call the C++ function GetData to C#?

My current codes in C# are:

[DllImport(".\\sdata.dll")] [return: MarshalAs(UnmanagedType.LPArray)] private static unsafe extern MainData[] GetData(int ID); // The struct MainData in my C# side is already "Marshalled"... //My function call is here: MainData[] SmpMapData = GetData(ID); 

When I compiled it, there's an exception: "Cannot marshal 'return value': Invalid managed/unmanaged type combination."

Sorry for the poor coding... Please help...

1

2 Answers 2

2
  • First, you need to remember that MarshalAs (explicit or implicit) for the return value essentially means "copy native structures content into managed structures".
  • Second, since the CLR marshaler only copies the data, if you do not free the memory you're allocated in the C++ function, you've got a memory leak to manage.
  • Third, this error is mainly due to the fact that the CLR marshaler has no way of knowing the length of the array returned by the native code, since you're basically returning a memory pointer and no length.

If you want to keep these memory structures as-is, I strongly suggest you to look into C++/CLI. You'll be able to wrap those complex types into mixed native/managed classes that will avoid you to copy the data around. This will help you keep the data marshaling to the bare minimum between native and managed code.

If you still want to use C# and no C++/CLI, you'll have to write a somehow smarter piece of code to unmarshal the data returned by the native code into managed data. You can look into Custom Marshaling for that.

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

Comments

0

I don't see how the .NET runtime could possibly know how many MainData are allocated in GetData(...).

Refactor your C++ code to consume an array to populate or return single MainDatas.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.