Click here to Skip to main content
15,884,686 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Help needed in calling imported DLL function

C#
[DllImport("ABC.DLL")
public static extern uint Func(IntPtr pOutput, IntPtr pNum);

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyStruct
{
  [MarshalAs(UnmanagedType.ByValArray, SizeConst=16)]
  public byte[] ID;
  [MarshalAs(UnmanagedType.LPStr)]
  public string Path;
  public IntPtr AnotherStruct;
  ...
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct AnotherStruct
{
  public ushort FormatType;
  public ushort FormatIndex;
}

// calling imported function...
MyStruct Arr=new MyStruct[16];
AnotherStruct FormatArr=new AnotherStruct[16];

IntPtr pArr=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyStruct))*16);

for(int i=0; i<16; i++) // allocate memory for AnotherStruct
Arr[i].AnotherSruct=Marshal.AllocHGlobal(Marshal.Sizeof(AnotherStruct[i]));

int iCount=0; IntPtr pCount=new IntPtr(iCount);
if(Func(out pArr, out pCount)!=0) return false;

return true;
}


Func() return true, but the pArr contents remain intact.
Did I do wrong in the structure conversion or memory allocation?

Thanks for any suggestions.
The C++ codes is as follow...

C
Func(MyStruct** pStruct, unsigned int* pNum);

struct MyStruct
{
  unsigned char ID[16];
  unsigned int* pPath;
  AnotherStruct* pFormat;
}
struct AnotherStruct
{
  unsigned int FormatType;
  unsigned int FormatIndex;
}
Posted
Updated 19-Oct-10 14:27pm
v3

1 solution

You can not directly use pointer notation in C#. If you are returning a pointer then catch the address in System.IntPtr type.

Steps to Follow
1. First allocate a memory in unmanaged area to copy the structure from managed code, using Marshal.AllocHGlobal().
2. Copy the structure using Marshal.Copy().

Refer some examples on MSDN or else have a look at .NET Interop Revisited.[^]
 
Share this answer
 
Comments
Syelixn 18-Oct-10 3:09am    
Am I right to say the imported function signature is changed the following?

[DllImport("ABC.DLL")
public static extern uint Function(IntPtr pStructure, uint* pNum);

And when calling the function as follow?

MY_STURCTURE[] pStructure = new MY_STRUCTURE[16];

IntPtr ptrStructure = new IntPtr();
Marshal.StructureToPtr(pStructure, ptrStructure, false);
GPUToaster™ 18-Oct-10 8:44am    
Change:
[DllImport("ABC.DLL")
public static extern uint Function(IntPtr pStructure, uint* pNum);

TO:
[DllImport("ABC.DLL")
public static extern uint Function(IntPtr pStructure, IntPtr pNum);
Syelixn 19-Oct-10 2:38am    
I got the following error when attempting to call Function()

Type 'Test.Class1+MY_STRUCTURE[]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

Here's how I call the imported DLL

MY_STRUCTURE[] Arr=new MY_STRUCTURE[16];
ANOTHER_STRUCTURE Format[] FormatArr=new ANOTHER_STRUCTURE[16];

IntPtr pArr=Marshal.AllocHGlobal(Marshal.SizeOf(Arr)); // Stepped error occurred here

for(int i=0; i<16; i++)
Arr[i].SupportedFormats=Marshal.AllocHGlobal(Marshal.SizeOf(FormatArr[i]));

int iCount=0; IntPtr pCount=new IntPtr(iCount);
if(Function(out pBSPArr, out pCount)!=0) return false;
Syelixn 19-Oct-10 2:51am    
Tried changing the following and run-time error disappeared. However, the Function() was successful but structures is untouched, i.e. no value. What could be wrong in the type conversion? Any suggestion is appreciated.

IntPtr pArr=Marshal.AllocHGlobal(Marshal.SizeOfTypeof(MY_STRUCTURE));

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900