"Tremendo" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> [I posted this in ...dotnet.framework.interop last week, with no luck. The question seems
> long, but
> I think that the answer should be easy and quick for someone who knows it.]
>
> Hi,
>
> I need to consume an unmanaged DLL from managed C#. The DLL is "ae766.dll". I have
> problems with one
> function in it. Who developed the DLL, provided the following information, regarding that
> function:
>
> -----------------------------
> Declaration
> -----------------------------
>
> extern "C" long __stdcall GetAnalyzerTraceData(LPSAFEARRAY FAR *);
>
> -----------------------------
> Description of the function
> -----------------------------
>
> GetAnalyzerTraceData(LPSAFEARRAY FAR *);
>
> A call to this routine will result in one trace of data being returned. A pointer to an
> array of
> BYTE type (in Visual Basic) should be passed in. This array
>
> will be allocated, initialized, and the data from the unit will be located in it as binary
> data.
>
>
> The structure of the data is as follows:
>
> Struct Data
> {
> char freq[7]; //center frequency (ascii characters) in units of kHz
> char span; //Decimal index indicating the current span
> char ref_level; //Decimal index indicating the current reference level
> char RBW[7]; //ascii characters indicating the current RBW
> unsigned char data[1000];
> unsigned char checksum; //checksum of the bytes
> unsigned char reserved; //unused
> }
>
> The total length of the data is 1018 bytes. The "data" portion of the structure is the
> actual trace
> data.
>
> A return value of 1 indicates success. A return value of 0 indicates a failure while
> attempting to
> read from the GSA-810.
>
> -----------------------------
>
>
> What C# code do I need to write, to "translate" the struct and to import the function? You
> don't
> need to write the whole code for me, because there are repeated data types (inside the
> struct, for
> instance). A hint about how to do it should be enough.
>
> Thank you very much.
>
The function takes a pointer to a safearray pointer (LPSAFEARRAY FAR *), the safearray being
a BYTE array. But in reality the BYTE[] is a flat structure of type Data. It's weird that a
record (UDT) is flatten-out like this, if you are sure about this, then the following is
how you could handle the marshaling:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct Data
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
internal char[] freq; //center frequency (ascii characters) in units of kHz
internal char span; //Decimal index indicating the current span
internal char ref_level; //Decimal index indicating the current reference level
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
internal char[] RBW; //ascii characters indicating the current RBW
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
internal byte[] data;
internal byte checksum; //checksum of the bytes
internal byte reserved; //unused
}
[DllImport("yourDll"), SuppressUnmanagedCodeSecurity]
static extern int GetAnalyzerTraceData
([Out, MarshalAs( UnmanagedType.SafeArray )] out byte[] sa);
IntPtr pnt = IntPtr.Zero;
try {
byte[] buffer = null;
if(GetAnalyzerTraceData(out buffer) == 0)
{
throw....
}
pnt = Marshal.AllocHGlobal(Marshal.SizeOf(data));
Marshal.Copy(buffer, 0, pnt, buffer.Length);
Data data = (Data)Marshal.PtrToStructure(pnt, typeof(Data));
// process data...
}
finally {
Marshal.FreeHGlobal(pnt);
}
Willy.
|