私はこれに数日をかけてきましたが、今のところどこに到着するのに役立つ多くの質問を読んだことがあります。しかし、まだ助けが必要です。C++のdll関数の戻り値としての構造体のポインタ
私は説明します。私は、C#でそれを使用するためにラップしたいC++ DLLを持っています。 DLLのドキュメントがありますが、何も変更することはできません。
DLL documentation
struct stChannel LookForAvailableChannels (const char *dataBaseFolder, int serialNumber, double firstLogTime, double lastLogTime)
私はまた、これらの構造体を持っている:機能の多くは、基本的なDLLIMPORTの設定で動作しますが、私が正常に動作しないいくつかの機能を持っている、これはその一つであるのでしよう
struct stChannelInfo
{
char ChannelTag[17];
char ChannelEnabled;
}
struct stChannel
{
int ChannelNumber;
struct stChannelInfo *ChannelInfo;
}
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();
私はこのコードを火災を呼び出すボタンがあります:異なる事があり、多くのことを読んだ後、私は「partialyは」機能するソリューションに来て
Estructura = LookForAvailableChannels("C:\\Folder", 12345678, FechaInicio, FechaFinal);
その後、私はEstructura.ChannelInfo.ChannelTagをマーシャリング:
string btListFile = Marshal.PtrToStringAnsi(Estructura.ChannelInfo.ChannelTag);
これは実際に動作しますが、それは私はそれが正しいことを知っているデータを返します。 stChannelInfo stChannel内のstructはポインタなので、私は配列の最初の要素しか受け取っていません。これをC#でどのように処理するのか分かりません。
それは方法で行われるべきである私が今使用して、このコードこと:
Marshal.PtrToStringAnsi(Estructura.ChannelInfo.ChannelTag);
は
Marshal.PtrToStringAnsi(Estructura.ChannelInfo[i].ChannelTag);
が、私は今だけでは動作しません使用していたすべてのものであるべき。助けていただければ幸いです。
ありがとうございます。
EDIT:
C#コード [StructLayout(LayoutKind.Sequential)] パブリック構造体stChannelInfo { [MarshalAs(UnmanagedType.LPStr、SizeConst:ユーザアドリアーノRepetti今持ってこれに
おかげ= 17)] 公開ストリングChannelTag; パブリックバイト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();
私はこのコードまで火を呼び出すボタンがあります。
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));
}
問題は今、それは私がここにAccessViolationExceptionを得ることです:
Estructura = LookForAvailableChannels("C:\\Folder", 12345678, FechaInicio, FechaFinal);
しかし、私は本当に知りませんのなぜ、私は助けていただければ幸いです。
ありがとう、本当に何が起こっているのか理解するのに役立ちます。すべてがOKですが、この部分 'Marshal.SizeOf(typeof(T)* index))'はコンパイルされません。この演算子は、この2つの型には適用できません。解決する方法はわかりません。 – JosueSB
_manual_マーシャリングを行う場合は、それも機能するはずです。ちょっとしたことがありますが、いくつかのヘルパー機能では合理的かもしれません。私が示唆したいのは、それらのまわりに完全なマネージラッパーを書くことです。 –
編集済みの私の前のコメント:D – JosueSB