I have a structure -->
public struct readers
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
public IntPtr[] tag_list;
};
Marshalling has to be done in between "IntPtr[] tag_list" & structure TAG_IN_PARAM
[StructLayout(LayoutKind.Sequential)]
internal struct TAG_IN_PARAM
{
public int vis_cnt;
public bool valid;
}
Also its an array as => TAG_IN_PARAM[] tag_list = new TAG_IN_PARAM[1000];
I want to pass structure "readers" from C# to C++ DLL. However, i have been doing marshalling but garbage value is coming on DLL side.
// allocating memory Marshal.StructureToPtr(tag_list[j], Reader.tag_list[j], false);
OR IF ANY OTHER WAY I CAN DO IT, PLEASE CONVEY. Any help would be appreciated. Thanks in Advance.
The C++ type that you are trying to match is, according to your comment:
class Readers
{
public:
TAG_IN_PARAM* tag_list;
};
That's a pointer to an array.
But your C# code declares an inline array. Your C# code would match this:
class Readers
{
public:
TAG_IN_PARAM tag_list[1000];
};
Obviously, that's not the way you want to go.
You'll need to change your C# code to make it match. Unfortunately it seems that the marshaller will not marshal an array as a pointer to the first element, when the array is inside a struct. Since the array is the only thing in the struct you should simply pass the array as a parameter.
Alternatively, if you absolutely need to pass the array in a struct then I think you need to marshal by hand. Like this.
public struct readers
{
public IntPtr tag_list;
};
And then you can simply pin your array.
TAG_IN_PARAM[] tag_list = ...;
GCHandle pinnedArray = GCHandle.Alloc(tag_list, GCHandleType.Pinned);
readers r;
r.tag_list = pinnedArray.AddrOfPinnedObject();
// call function passing r
pinnedArray.Free();
Unfortunately that does not quite work because C# bool
is not blittable. So you could resolve that by using a different type for that field. For example byte
or int
depending on what's on the C++ side.
Yet another option is Marshal.StructureToPtr
on each field. That would run like this:
TAG_IN_PARAM[] tag_list = ...;
int structSize = Marshal.SizeOf(typeof(TAG_IN_PARAM));
r.tag_list = Marshal.AllocHGlobal(tag_list.Length*structSize);
IntPtr ptr = r.tag_list;
for (int i = 0; i < tag_list.Length; i++)
{
Marshal.StructureToPtr(tag_list[i], ptr, false);
ptr += structSize;
// or on older versions of .net without arithmetic support on IntPtr
// ptr = (IntPtr) (long)ptr + structSize;
}
// call function passing r
Marshal.FreeHGlobal(r.tag_list);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.