• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1005
  • Last Modified:

(IMPORTANT) Using an API C in C#

Gentlemen Good Day,
 
I am trying to write a C# class wrapper for Cisco's VPN Client API which they provide a VPNAPI.h. I am trying to wrap the header definitions so that I may be able to use their VPNAPI.DLL.
 
So here is a little summary:
 
//////////////////////////////////
/// THE EASY PART          ///
/////////////////////////////////
A bunch of definitions transformation and convertion

C++
typedef int32_t vpn_error_t;   //! return type for most functions

C#
using vpn_error_t = System.Int32; // return type for most functions


C++
//! API version number
#define VPNAPI_VERSION 0x00010000
 
C#
/// <summary>
/// API version number
/// </summary>
public enum VPNAPI_VERSION : uint
{
    VPNAPI_VERSION =0x00010000 // Version
}
 
Some structures
C++
struct vpn_connect_error
{
    vpn_error_t error;
    uint32_t is_remote;
    char * delete_reason;
 
    uint32_t reserved[2];
};
 
C#
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public class vpn_connect_error
{
    public vpn_error_t error;
    public System.UInt32 is_remote;
    public StringBuilder delete_reason;
 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=(int)2)]
    public System.UInt32[] reserved;
};
 
Function calls:
C++
DLL_EXPORT_NAME vpn_error_t vpn_api_init(uint32_t * version);
 
C#
[DllImport("vpnapi.dll",CharSet=CharSet.Auto)]
public extern static vpn_error_t vpn_api_init(System.UIntPtr version);
 
 
 
//////////////////////////////////
/// THE HARD PART ///
/////////////////////////////////
Now here is something I need some assistance:
///////////////////////////////////////////////////////
//! return type for most functions
typedef int32_t vpn_error_t;
///////////////////////////////////////////////////////
//! Possible states for a VPN connection.
typedef enum
{
VPN_MIN_STATE = -1,
VPN_STATE_IDLE,
// delete some states to save place
VPN_STATE_CONNECTED,
VPN_MAX_STATE,
} vpn_state_t;
///////////////////////////////////////////////////////
typedef union
{
    struct
    {
        uint32_t pad[3];
        //! IP address in network order
        struct in_addr addr; //in_addr declared in winsock.h
    } ipv4;
} vpn_ip_addr_t;
///////////////////////////////////////////////////////
struct vpn_connect_error
{
    vpn_error_t error;
    uint32_t is_remote;
    char * delete_reason;
    uint32_t reserved[2];
};
///////////////////////////////////////////////////////
typedef void (*vpn_state_change_cb) (vpn_state_t state, const vpn_ip_addr_t * peer, const struct vpn_connect_error*);
///////////////////////////////////////////////////////
typedef void *vpn_channel_t;
///////////////////////////////////////////////////////
struct vpn_callback_table
{
    //-- deleted some callbacks to save place
    //! state change callback
    vpn_state_change_cb fp_state_change;
};
///////////////////////////////////////////////////////
DLL_EXPORT_NAME vpn_error_t vpn_channel_init(vpn_channel_t * channel, uint32_t * msgtypes, const struct vpn_callback_table *callbacks);
///////////////////////////////////////////////////////
 
If you can help me figure out these few lines of C language code and wrap it in a C# class I will truly love you... I have been stuck on this parts for a week now and I would love some help at this point.
 
If the above part was an API you needed to use in your C# application how would you implement this?

Thank you,
 
Yama Kamyar
0
yamazed
Asked:
yamazed
1 Solution
 
c_myersCommented:
DLL_EXPORT_NAME vpn_error_t vpn_channel_init(vpn_channel_t * channel, uint32_t * msgtypes, const struct vpn_callback_table *callbacks);

Well, you know what vpn_error_t is, and vpn_channel_t will just be an IntPtr to (who knows what -- it's void* after all). You can probably figure out the [DllImport] stuff since it's not unlike the others.

The vpn_callback_table struct will be a regular struct like your others, except that it's sole field will be a delegate that mimics the vpn_state_change_cb callback.

Sorry I can't test this, I'm trusting blind luck here, but my best guess is that your delegate would look like:

public delegate void vpn_state_change_cb( vpn_state_t state, vpn_ip_addr peer, vpn_connect_error conError );

So your struct might look something like:

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public class vpn_callback_table
{
    public vpn_state_change_cb StateChangeCallback;
}

Then, when you call their method, it'll might look something like:

// set up the channel, the vpn_ip_addr/peer, etc
...

vpn_error_t vpnError;
vpn_callback_table callbackTab;

callbackTab.StateChangeCallback = new vpn_state_change_cb( YourCallbackMethodImplHere );

vpnError = vpn_channel_init( channel, peer, callbackTab );
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now