Point to array in Csharp and native dll

B

borewill

I have a dll writtin in native C++ which provide such interface:

typedef struct _PARAM
{
LPWSTR swName;
DWORD dwOptions;
} PARAM,*PPARAM,*LPPARAM;

DLLEXPORT BOOL CALLBACK Function(LPPARAM pData);

Call as:

PARAM ParamsArray[]={
{L"Anna",202},
{L"John",324},
{L"Doe",4094},
{L"etc..",3003},
{NULL,0}
};
Function((PPARAM)&ParamsArray);

How to call this native dll from managed C# code?
How to easy init array of such params in C# and correctly send it to
dll function?

I created C# class
namespace test
{
class NativeDll
{
[StructLayout(LayoutKind.Sequential)]
public struct PARAM
{
[MarshalAs(UnmanagedType.LPStr)]
public String swName;
public uint dwOptions;
};

[DllImport("Easymovedll.dll", CallingConvention =
CallingConvention.Winapi,
CharSet=CharSet.Unicode,EntryPoint="_Function")]
public static extern bool Function(ref PARAM[] PPARAM);
}
}


Calling in C#:
using test;
NativeDll.PARAM[] ParamsArray=new NativeDll.PARAM[2];
PARAM[0].swName="john";
PARAM[0].dwOptions=2093;
PARAM[1].swName=null;
PARAM[1].dwOptions=0;
NativeDll.Function(ref ParamsArray);

But this is not give me correct array is I want. What I doing wrong?
 
M

Mattias Sjögren

How to easy init array of such params in C#

It would be slightly easier if you add a contructor to the PARAM
struct.

[DllImport("Easymovedll.dll", CallingConvention =
CallingConvention.Winapi,
CharSet=CharSet.Unicode,EntryPoint="_Function")]
public static extern bool Function(ref PARAM[] PPARAM);
^^^

Try it without the ref modifier.


Mattias
 
B

borewill

[DllImport("Easymovedll.dll", CallingConvention =
CallingConvention.Winapi,
CharSet=CharSet.Unicode,EntryPoint="_Function")]
public static extern bool Function(ref PARAM[] PPARAM);

^^^

Try it without the ref modifier.

Yes this is work but when other functions is called, it seems to be
array was destroyed, and it unpossible to use this array. How to send
permanent point to PARAM array, so it will be accessible when other
dll functions is called?
 
M

Mattias Sjögren

Yes this is work but when other functions is called, it seems to be
array was destroyed, and it unpossible to use this array. How to send
permanent point to PARAM array, so it will be accessible when other
dll functions is called?

You have to keep the array pinned in memory as long as the native code
uses it. You can explicitly pin an object using the GCHandle type.

But since pinning for longer durations can hurt GC, it might be a
better idea to allocate a buffer from a native heap using for example
Marshal.AllocHGlobal and pass that to the DLL instead. You can then
retrieve the PARAM values from the buffer with Marshal.PtrToStructure.


Mattias
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top