C function in VB.NET
I'm having some problems calling a C function from a DLL, and was hoping someone could help me out. The function is returning -101 which translates as a "bad parameter". The values I am passing have been returned from another, successful function call, so my current assumption is that I've built the structure incorrectly. Any help is appreciated.
The function definition is:
int sm_switch_channel_input(struct sm_switch_channel_parms *switchp)
Parameters
*switchp (a structure of the following type):
typedef struct sm_switch_channel_parms {
tSMChannelId channel; /* in */
tSM_INT st; /* in */
tSM_INT ts; /* in */
enum kSMTimeslotType type; /* in */
} SM_SWITCH_CHANNEL_PARMS;
typedef struct tSMChannelId_struct *tSMChannelId;
typedef int tSM_INT;
enum kSMTimeslotType {
kSMTimeslotTypeALaw,
kSMTimeslotTypeMuLaw,
kSMTimeslotTypeData,
};
And here is how I've defined & called it...
Enum kSMTimeslotType
kSMTimeslotTypeALaw = 0
kSMTimeslotTypeM开发者_运维技巧uLaw = 1
kSMTimeslotTypeData = 2
End Enum
Public Structure sm_switch_channel_input_params
<MarshalAsAttribute(UnmanagedType.SysInt)> _
Public channel As IntPtr
<MarshalAsAttribute(UnmanagedType.I4)> _
Public stream As Integer
<MarshalAsAttribute(UnmanagedType.I4)> _
Public timeslot As Integer
<MarshalAsAttribute(UnmanagedType.U4)> _
Public tsType As kSMTimeslotType
End Structure
<DllImport("TiNG.dll")> _
Private Shared Function sm_switch_channel_input_iPsCtiie1_3__(ByRef x As sm_switch_channel_input_params) As Integer
End Function
Dim sscip As sm_switch_channel_input_params
Dim err as Integer
sscip.channel = chanA
sscip.stream = streamA
sscip.timeslot = timeSlotA
sscip.tsType = kSMTimeslotType.kSMTimeslotTypeMuLaw
err = sm_switch_channel_input_iPsCtiie1_3__(sscip)
I think the SysInt attribute is what's causing your problem. It's not necessary in this case because IntPtr
will always marshal correctly based on the current platform. You're also missing a StructLayout
attribute
There are a couple of other attributes which are not necessary as well. I would try using the following definition
Enum kSMTimeslotType
kSMTimeslotTypeALaw = 0
kSMTimeslotTypeMuLaw = 1
kSMTimeslotTypeData = 2
End Enum
<StructLayout(LayoutKind.Sequential)> _
Public Structure sm_switch_channel_input_params
Public channel As IntPtr
Public stream As Integer
Public timeslot As Integer
Public tsType As kSMTimeslotType
End Structure
Judging by the name of the function in your VB code, it is a C++ function, and exported as such. Therefore, it doesn't use the "stdcall" calling convention (which P/Invoke assumes by default), but "thiscall" (which VC++ uses for all non-vararg C++ functions). So try this:
<DllImport("TiNG.dll", CallingConvention := CallingConvention.ThisCall)> _
Private Shared Function sm_switch_channel_input_iPsCtiie1_3__ ...
The more appropriate way to fix this would be to decorate the function in C code with extern "C"
and __stdcall
instead:
extern "C" {
int __stdcall sm_switch_channel_input(struct sm_switch_channel_parms *switchp)
...
}
Then your original P/Invoke declaration should work as is.
As a side note, all your MarshalAs
attributes are redundant (they specify behavior which is already the default for types to which you apply it), so you can drop them altogether.
精彩评论