(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
yamazedAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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 );

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.