Exposing method with char[][SIZE] parameter

M

Mike

In my RPC interface, a have a number of functions with this generic
layout:

BOOL APIENTRY XYZ(int count, char list[][SIZE_XYZ_NAME]);

These XYZ functions are prepared for RPC client/server marshalling and
the protocol maps with the IDL for RPC (DCE).

An example usage in C/C++ is

typedef char TXYZName[SIZE_XYZ_NAME];
....

TXYZName *names = new TXYZName[count];
if (GetXYZNames(count, names)) {
....
}

In VB.NET I can get the job done, like so:

Public Shared Function GetXYZNames() As String()
Dim list As String() = {}
Dim count As Integer = GetXYZCount()
If (count > 0) Then
ReDim list(count - 1)
''---- THIS IS RPC CLIENT/SERVER INEFFICIENT -----
Dim i As Integer
For i = 0 To count - 1
list(i) = GetXYZName(i)
Next
''-----------------------------
End If
Return list
End Function

by return a string list built by calling the server's GetXYZName()
function COUNT times. This is inefficient because the redundant calls
to the server to get one item at a time. So it would be useful to do this:

Public Shared Function GetXYZNames() As String()
Dim list As String() = {}
Dim count As Integer = GetXYZCount()
If (count > 0) Then
ReDim list(count - 1)
GetXYZNames(count,list) <--- one shot server call
End If
Return list
End Function

However, I am failing to get the proper unmanaged DLLImport and
structuring for this direct server call.

I tried this:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TXYZName
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=SIZE_XYZ_NAME)> _
Public Name As String
End Structure

<DllImport("wcsrv2.dll", SetLastError:=True)> _
Public Function GetXYZNames _
( _
byval count as integer, _
byval list as TXYZName() _
) As Boolean
End Function

But this produces an incorrect unmanaged/managed exception.

I tried this too:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TXYZList
Public Name() As TXYZName
End Structure

<DllImport("wcsrv2.dll", SetLastError:=True)> _
Public Function GetXYZNames _
( _
byval count as integer, _
byval list as TXYZList _
) As Boolean
End Function

..
dim alist as TXYZList
redim alist.Name(count-1)
if GetXYZNames(count, alist) then
end if

But this produces an incorrect HRESULT parameter exception.

Any tips on the proper DLLImport and structure layout?

Thanks

--
 
D

dunawayc

In my RPC interface, a have a number of functions with this generic
layout:

BOOL APIENTRY XYZ(int count, char list[][SIZE_XYZ_NAME]);

These XYZ functions are prepared for RPC client/server marshalling and
the protocol maps with the IDL for RPC (DCE).

An example usage in C/C++ is

typedef char TXYZName[SIZE_XYZ_NAME];
....

TXYZName *names = new TXYZName[count];
if (GetXYZNames(count, names)) {
....
}

In VB.NET I can get the job done, like so:

Public Shared Function GetXYZNames() As String()
Dim list As String() = {}
Dim count As Integer = GetXYZCount()
If (count > 0) Then
ReDim list(count - 1)
''---- THIS IS RPC CLIENT/SERVER INEFFICIENT -----
Dim i As Integer
For i = 0 To count - 1
list(i) = GetXYZName(i)
Next
''-----------------------------
End If
Return list
End Function

by return a string list built by calling the server's GetXYZName()
function COUNT times. This is inefficient because the redundant calls
to the server to get one item at a time. So it would be useful to do this:

Public Shared Function GetXYZNames() As String()
Dim list As String() = {}
Dim count As Integer = GetXYZCount()
If (count > 0) Then
ReDim list(count - 1)
GetXYZNames(count,list) <--- one shot server call
End If
Return list
End Function

However, I am failing to get the proper unmanaged DLLImport and
structuring for this direct server call.

I tried this:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TXYZName
<MarshalAs(UnmanagedType.ByValTStr, sizeconst:=SIZE_XYZ_NAME)> _
Public Name As String
End Structure

<DllImport("wcsrv2.dll", SetLastError:=True)> _
Public Function GetXYZNames _
( _
byval count as integer, _
byval list as TXYZName() _
) As Boolean
End Function

But this produces an incorrect unmanaged/managed exception.

I tried this too:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TXYZList
Public Name() As TXYZName
End Structure

<DllImport("wcsrv2.dll", SetLastError:=True)> _
Public Function GetXYZNames _
( _
byval count as integer, _
byval list as TXYZList _
) As Boolean
End Function

..
dim alist as TXYZList
redim alist.Name(count-1)
if GetXYZNames(count, alist) then
end if

But this produces an incorrect HRESULT parameter exception.

Any tips on the proper DLLImport and structure layout?

Thanks

--

I'm not sure, but be aware that in VB.Net and other .Net languages,
Integer is 4 bytes. Is the count argument of your RPC interface also
a 4 byte integer?

Just one thing to keep in mind.

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top