I have decalred the following structure
<StructLayout(LayoutKind.Sequential, Pack:=1)>
Public Structure Scanpara
Public cmd As Shor
Public fdc As Shor
Public dsf As Int3
Public boxcar As Shor
Public average As Shor
Public chan_ena() As Shor
Public scan_dark As Shor
Public correct_dark As Shor
Public extrig As Shor
Public upper4chan As Shor
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8192)>
Public sdat() As Singl
Public Sub Initialize(
ReDim chan_ena(3
ReDim sdat(8191
End Su
End Structur
[/code
And the following function declaration
Declare Function OOI_DoScan Lib "OOIDrv32.dll" (ByRef pVal As Scanparam) As Shor
The original function (from C++ Header) looks like this
short EXPORTED OOI_DoScan(SCANPARM FAR *); // perform 1 acquisitio
The function executes just fine, however if you look at my origianl declaration of the C structure, you'll see that what I really want is a 2-D array (4X2048). If I assume that my first row of data is in positions 0-2047 of the returned (sdat) array, it looks like I'm missing one point off of the front and back of that array (2047 has no data, and position 1 does not either..I expect position 0 to have no data...strange behavior of the third party dll). If I write a C++ COM object to do the same call, and use it in the VB .NET program, I do not see this behavior. I am assuming that this is because I am passing in a 1-D array and making possibly erroneous assumptions about the order in which they will be written to
Decalre a 2-D array you say? HA HA HA! If I decalre the stucture in the following way
<StructLayout(LayoutKind.Sequential, Pack:=1)>
Public Structure Scanpara
Public cmd As Shor
Public fdc As Shor
Public dsf As Int3
Public boxcar As Shor
Public average As Shor
Public chan_ena() As Shor
Public scan_dark As Shor
Public correct_dark As Shor
Public extrig As Shor
Public upper4chan As Shor
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8192)>
Public sdat(,) As Singl
Public Sub Initialize(
ReDim chan_ena(3
ReDim sdat(3, 2047
End Su
End Structur
then when I call my scan function, I get the error
System.TypeLoadException: Con not marshal field sdat of the type OOResourceServer.Scanparam: This type can not be marshaled as a structure field
To say the least, I am frustrated. Is my line of work, lab automation, I often have to interact with third party dlls that have complicated structures that need to be passed in by reference, to do things like high data rate scans. Althought there is the workaround of using C++ to develop a COM wrapper, I need to be able to tell VB .NET programmers how to do this...and they may not be C++ programmers themselves. This seems silly...why can't VB .NET understand that I am passing a 2_D array of float values...is that too much to ask?? There is absolutely not material that I have found that addresses this problem...all examples use 1-D arrays
I will stop now, lest I begin ranting (If I haven't already)
Thanks
Stev
----- Rob Teixeira [MVP] wrote: ----
You might want to post your VB version of the structure definition. Thi
should work fine. When defining the structure in VB, make sure to use th
MarshalAs attribute, and specify the unamangedtype as ByValArray (for th
arrays), including the SizeConst and the ArraySubType properties of th
attribute
Also, you don't need to use Marshal.StructureToPtr. When defining the C DL
function export in VB, just set the structure parameter to ByRef instead o
ByVal, and you can pass a structure variable of this type directly to th
function
-Rob Teixeira [MVP
"Steve Turner" <an*******@discussions.microsoft.com> wrote in messag
news:94**********************************@microsof t.com..
I have read several interesting posts on passing structures to C dlls, bu
none seem to cover the following case. The structure (as seen in C) is a
follows:
typedef struct tag_scanparm
{
short cmd;
short fdc;
WORD dsf;
short boxcar;
short average;
short chan_ena[\4];
short scan_dark;
short correct_dark;
short extrig;
short upper4chan;
float sdat[\4][\2048]
} SCANPARM; The real problem seems to be with the arrays. Even using attributes and
specifying a size when I decalre the structure in VB, I can't get this to
work. It has to be passed by reference, and when I call "GetType" as a part
of my call to Marshall.StructureToPtr, I get an error message to the effect
that my structure cannot be marshalled as an unmanaged type. Please forgive the fact that I don't have the exact error message
handy...I tried getting this to work for about a day, scanning all types of
message boards, and finally threw in the towel and created a COM object in
C++ that wrapped the calls to this 3rd Party dll. That's OK for me, but for
some of our customers who use VB exclusively it would be nice to know how to
do this directly from VB...there has to be a way, and I think I was close! Any help would be greatly appreciated! Thanks,
Steve