Reputation: 25
I have an ANSI DLL which has a function declared as follows:
long GetInfo(
THE_INFO* pINFO
)
The structure THE_INFO is declared as follows:
typedef struct tagTHE_INFO
{
unsigned long dwSize;
char szCopyright[64];
long nWidth;
long nHeight;
long nObjectCount;
int bThumbnailImage;
long nThumbnailImageWidth;
long nThumbnailImageHeight;
int bThumbnailObject;
long nThumbnailObjectWidth;
long nThumbnailObjectHeight;
}
THE_INFO;
The DLL documentation says that all functions use the stdcall calling convention for passing parameters. Further it defines:
unsigned long As Unsigned 32-bit integer.
char As Signed 8-bit integer.
long As Signed 32-bit integer.
int As Signed 32-bit integer.
A COM wrapper DLL I used years ago is no longer supported and so I have to deal with the DLL directly. I declared the DLL call and structure in my code as follows:
Declare Ansi Function GetInfo Lib "ADLL.dll" (pINFO As THE_INFO) As Integer
<StructLayout(LayoutKind.Sequential)> Friend Class THE_INFO
Public dwSize As UInteger
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=64)>
Public szCopyright As String
Public nWidth As Integer
Public nHeight As Integer
Public nObjectCount As Integer
Public bThumbnailImage As Integer
Public nThumbnailImageWidth As Integer
Public nThumbnailImageHeight As Integer
Public bThumbnailObject As Integer
Public nThumbnailObjectWidth As Integer
Public nThumbnailObjectHeight As Integer
End Class
Dim Info As New THE_INFO With {.dwSize = 104}
ErrorCode = GetInfo(Info)
The function call succeeds indicating this in returning zero, so at least everything seems to be declared correctly. But when I look into the returned Info structure, all structure members are still reflecting the initial values. But at least the nWidth and nHeight members must have values greater than zero since the underlying data is a valid object.
I think it has something to do with the pinvoking, but I can't explain to me, what I have done wrong.
Upvotes: 0
Views: 94
Reputation: 941970
You would normally declare the structure with the Structure keyword and pass it ByRef:
<StructLayout(LayoutKind.Sequential)> _
Friend Structure THE_INFO
'' etc..
End Structure
Declare Ansi Function GetInfo Lib "ADLL.dll" (ByRef pINFO As THE_INFO) As Integer
Declaring it as a Class is okay too but then you'll have to pass it ByVal and tell the pinvoke marshaller explicitly that the object needs to be marshaled back. Like this:
Declare Ani Function GetInfo Bar Lib "ADLL.dll" (<[In](), Out()> ByVal pINFO As THE_INFO) As Integer
It is the missing <Out>
attribute that is causing your problem. You also need <In>
since you initialize the dwSize member of the structure.
Upvotes: 2