I've been several days into this, and I've read a lot of questions that helped me to arrive to where I am right now. But I still need some help.
I will explain. I have a C++ DLL that I want to wrap for use it in c#. I have the documentation of the DLL, but I can't change anything of it. A lot of functions work with basic dllimport setup, but I have some functions that doesn't work properly, this is one of them:
DLL documentation
struct stChannel LookForAvailableChannels (const char *dataBaseFolder, int serialNumber, double firstLogTime, double lastLogTime)
I also have these structs:
struct stChannelInfo
{
char ChannelTag[17];
char ChannelEnabled;
}
struct stChannel
{
int ChannelNumber;
struct stChannelInfo *ChannelInfo;
}
So trying different things, and after reading a lot, I've come to a solution that "partialy" works:
C# Code
[StructLayout(LayoutKind.Sequential)]
public struct stChannelInfo
{
public IntPtr ChannelTag;
public byte ChannelEnabled;
};
[StructLayout(LayoutKind.Sequential)]
public struct stChannel {
public int ChannelNumber;
public stChannelInfo ChannelInfo;
};
[DllImport("NG.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern stChannel LookForAvailableChannels(string dataBaseFolder, int serialNumber, double firstLogTime, double lastLogTime);
stChannel Estructura = new stChannel();
I have a button that calls fires up this code:
Estructura = LookForAvailableChannels("C:\\Folder", 12345678, FechaInicio, FechaFinal);
Then I marshal Estructura.ChannelInfo.ChannelTag:
string btListFile = Marshal.PtrToStringAnsi(Estructura.ChannelInfo.ChannelTag);
This actually works, it returns data I know it's correct. But I'm only receiving the first element of an array, because stChannelInfo struct inside stChannel is a pointer, and I don't know how to handle this in c#.
It should be done in a way that this code I use right now:
Marshal.PtrToStringAnsi(Estructura.ChannelInfo.ChannelTag);
Should be
Marshal.PtrToStringAnsi(Estructura.ChannelInfo[i].ChannelTag);
But everything i've used right now just doesn't work. I would appreciate any help.
Thank you.
EDIT:
Thanks to user Adriano Repetti now I have this:
C# Code [StructLayout(LayoutKind.Sequential)] public struct stChannelInfo { [MarshalAs(UnmanagedType.LPStr, SizeConst = 17)] public string ChannelTag; public byte ChannelEnabled; };
[StructLayout(LayoutKind.Sequential)]
public struct stChannel {
public int ChannelNumber;
public IntPtr ChannelInfo;
};
[DllImport("NG.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern stChannel LookForAvailableChannels(string dataBaseFolder, int serialNumber, double firstLogTime, double lastLogTime);
stChannel Estructura = new stChannel();
I have a button that calls fires up this code:
Estructura = LookForAvailableChannels("C:\\Folder", 12345678, FechaInicio, FechaFinal);
var channelinf = (stChannelInfo)Marshal.PtrToStructure(Estructura.ChannelInfo, typeof(stChannelInfo));
for (int i = 0; i < 4; i++)
{
var ptr = IntPtr.Add(Estructura.ChannelInfo, Marshal.SizeOf(typeof(stChannelInfo)) * i);
var channelll = (stChannelInfo)Marshal.PtrToStructure(ptr, typeof(stChannelInfo));
}
The problem now it's that I get an AccessViolationException here:
Estructura = LookForAvailableChannels("C:\\Folder", 12345678, FechaInicio, FechaFinal);
But I don't really know why, I would appreciate any help.