开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜