当前位置:编程学习 > C#/ASP.NET >>

求C#调用联通短信网关UniAPIDll.dll的代码

已经查阅了好多文章,都没有最终成功的解决代码,哪位大侠可以发送下?
dingrui.cn@gmail.com

小弟感激不尽。

ps:不要傲天API。

C语言头文件
************************************************************************************************
// uniapi interface header file
#ifndef UNIAPI_H
#define UNIAPI_H
#if defined(__cplusplus)           // should test this macro in unix.
extern "C"
{
#endif

//macro define
#define LOGINFO_IP_LEN             ((int)15)
#define LOGINFO_USER_LEN           ((int)16)
#define LOGINFO_PWD_LEN            ((int)16)

#define SGIP_NUMBER_LEN            ((int)21)
#define SGIP_CORP_ID_LEN           ((int)5)
#define SGIP_SERVICE_TYPE_LEN      ((int)10)
#define SGIP_FEE_VALUE_LEN         ((int)6)
#define SGIP_TIME_LEN              ((int)16)
#define SGIP_MSG_LEN               ((int)255)
#define SGIP_RESERVE_LEN           ((int)8)

#define SGIP_DELIVER_MSG           ((int)0)
#define SGIP_REPORT_MSG            ((int)1)

// error code define
// 1, the errors that 'InitSgipAPI' function return
#define SGIP_INIT_SUCCESS          ((int)0)
#define SGIP_INIT_AGAIN            ((int)-1)
#define SGIP_INIT_PARA_NULL        ((int)-2)
#define SGIP_INIT_OS_ERROR         ((int)-3)
#define SGIP_INIT_APP_ERROR        ((int)-4)
#define SGIP_INIT_PARA_ERROR       ((int)-5)
#define SGIP_INIT_NET_ERROR        ((int)-6)
// 2, the errors that 'SendMTMessage' function return, when error code > 0, they come from gw
#define SGIP_SEND_SUCCESS          ((int)0)
#define SGIP_SEND_NO_INIT          ((int)-1)
#define SGIP_SEND_PARA_NULL        ((int)-2)
#define SGIP_SEND_PARA_ERROR       ((int)-3)
#define SGIP_SEND_NO_NETLINK       ((int)-4)
#define SGIP_SEND_SYSTEM_ERROR     ((int)-5)
#define SGIP_SEND_GETRESULT_ERROR  ((int)-6)
#define SGIP_SEND_MAKESEQNO_FAIL   ((int)-10)
#define SGIP_SEND_SETTIMER_FAIL    ((int)-11)
#define SGIP_SEND_SENDTONET_FAIL   ((int)-12)
#define SGIP_SEND_RECVRSP_TIMEOUT  ((int)-13)
// 3, the errors that 'RecvMessage' function return
#define SGIP_RECV_SUCCESS          ((int)0)
#define SGIP_RECV_NO_INIT          ((int)-1)
#define SGIP_RECV_PARA_NULL        ((int)-2)
#define SGIP_RECV_PARA_ERROR       ((int)-3)
#define SGIP_RECV_SYSTEM_LOCKERR   ((int)-4)
#define SGIP_RECV_TIMEOUT_BACK     ((int)-5)
#define SGIP_RECV_SYSTEM_ERROR     ((int)-6)

// sturct define
#pragma pack( 1 )
typedef struct loginInfo_tag
{
     unsigned int spNodeId;                              // sp node code, should be assigned by gw
     char         gwIp[LOGINFO_IP_LEN + 1];
     int          gwPort;
     char         loginGwUser[LOGINFO_USER_LEN + 1];
     char         loginGwPwd[LOGINFO_PWD_LEN + 1];
     char         appIp[LOGINFO_IP_LEN + 1];             // provide sgip server on the ip.
     int          appPort;                               // provide sgip server at the port
     char         gwLinkUser[LOGINFO_USER_LEN + 1];      // gw use the username to link app  
     char         gwLinkPwd[LOGINFO_PWD_LEN + 1];        // gw use the password to link app
} LoginInfo;

typedef struct
{
    unsigned int node;
    unsigned int time;
    unsigned int number;
} SequenceNo;

typedef struct
{
    char           pSpNumber[SGIP_NUMBER_LEN];
    char           pChargeNumber[SGIP_NUMBER_LEN];
    char           pUserNumber[SGIP_NUMBER_LEN];
    char           pCorpId[SGIP_CORP_ID_LEN];
    char           pServiceType[SGIP_SERVICE_TYPE_LEN];
    unsigned char  feetype;
    char           pFeeValue[SGIP_FEE_VALUE_LEN];
    char           pGivenValue[SGIP_FEE_VALUE_LEN];
    unsigned char  agentflag;
    unsigned char  morelatetomtflag;
    unsigned char  priority;
    char           pExpireTime[SGIP_TIME_LEN];            // user write format:"yymmddhhmmss"
    char           pScheduleTime[SGIP_TIME_LEN];          // user write format:"yymmddhhmmss"
    unsigned char  reportflag;
    unsigned char  tppid;
    unsigned char  tpudhi;
    unsigned char  msgcoding;
    unsigned char  msgtype;
    unsigned int   msglen;
    char           pContent[SGIP_MSG_LEN];
    char           pReserve[SGIP_RESERVE_LEN];
} Submit;

typedef struct
{
    char           pUserNumber[SGIP_NUMBER_LEN];
    char           pSpNumber[SGIP_NUMBER_LEN];
    unsigned char  tppid;
    unsigned char  tpudhi;
    unsigned char  msgcoding;
    unsigned int   msglen;
    char           pContent[SGIP_MSG_LEN];
    char           pReserve[SGIP_RESERVE_LEN];
} Deliver;

typedef struct
{
    SequenceNo     relationsn;
    unsigned char  reporttype;   
    char           pUserNumber[SGIP_NUMBER_LEN];
    unsigned char  state;    
    unsigned char  errcode;  
    char           pReserve[SGIP_RESERVE_LEN];
} Report;
#pragma pack( )   // can't resume user's packing alignments.

// interface function
#ifdef WIN32    // only for windows
#ifndef UNIAPI_DLL
#define UNIAPI_DLL _declspec(dllimport)
#endif
#else
#ifndef UNIAPI_DLL
#define UNIAPI_DLL
#endif
#endif

// when compile with static lib 
/*
#undef UNIAPI_DLL
#define UNIAPI_DLL
*/

UNIAPI_DLL int InitSgipAPI( char *path, LoginInfo *pLoginInfo );
UNIAPI_DLL int SendMTMessage( Submit *pMsg, SequenceNo *pMsgId );
UNIAPI_DLL int RecvMessage( int *piMsgType, void *pMsgBuf, int iBufSize );

#if defined(__cplusplus)
}
#endif 

**********************************************************************************************

三个方法
InitSgipAPI
SendMTMessage
RecvMessage

通过C# invoke 调用。

        //1. 初始化函数
        [DllImport("UniAPIDll.dll", EntryPoint = "InitSgipAPI", CharSet = CharSet.Unicode)]
        public static extern int InitSgipAPI(StringBuilder  path, ref   LoginInfo pLoginInfo);

        //记录SP登录GW或者GW登录SP的登录信息结构
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct LoginInfo
        {
            public uint spNodeId;         //sp的设备代码,应该由网关为其分配

            [MarshalAs(UnmanagedType.ByValArray  , SizeConst = 16)]
            public char[] gwIp;             //网关的侦听IP地址

            public int gwPort;           //网关的侦听端口

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] loginGwUser;      //sp登陆网关时所用的用户名

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] loginGwPwd;       //sp登陆网关时所用的密码

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] appIp;            //sp的侦听IP地址

            public int appPort;          //sp的侦听端口

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] gwLinkUser;       //网关登陆sp时所用的用户名

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] gwLinkPwd;        //网关登陆sp时所用的密码
        }

       private void button1_Click(object sender, EventArgs e)
        {
            LoginInfo ploginInfo = new LoginInfo();
            ploginInfo.spNodeId = 3002300000;
            ploginInfo.gwIp = "               ".ToCharArray();
            ploginInfo.gwPort = 9001;
            ploginInfo.loginGwUser = "                ".ToCharArray();
            ploginInfo.loginGwPwd = "                    ".ToCharArray();
            ploginInfo.appIp = "                 ".ToCharArray();
            ploginInfo.appPort = 8000;
            ploginInfo.gwLinkUser = "                ".ToCharArray();
            ploginInfo.gwLinkPwd = "               ".ToCharArray();

            string str = "D:\\我的文档\\Downloads\\dnntest\\WindowsFormsApplication2\\WindowsFormsApplication2\\bin\\Debug";

            textBox1.Text = InitSgipAPI(str, ref  ploginInfo).ToString();

}

InitSgipAPI总是报“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 ”
--------------------编程问答-------------------- 用C#可以直接调用吗? --------------------编程问答-------------------- C# 到 c++ 参数 对照表
--------------------编程问答-------------------- C# 到 c++ 参数 对照表
--------------------编程问答-------------------- C# 调用 c++ 类型 
注意:
为什么 有的要加 ref 为什么有的要用 char 有的要加 int 有的要用 ref int 
一个 外国老 写的 国人 翻译了的
现在 找 不 到 了,自己找  --------------------编程问答-------------------- 两个问题:
1、结构体映射错误,正确做法:

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,Pack=1)]
  public struct LoginInfo
  {
     public uint spNodeId; //sp的设备代码,应该由网关为其分配
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
     public string gwIp; //网关的侦听IP地址
     public int gwPort; //网关的侦听端口
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  loginGwUser; //sp登陆网关时所用的用户名
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  loginGwPwd; //sp登陆网关时所用的密码
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
     public string  appIp; //sp的侦听IP地址
     public int appPort; //sp的侦听端口
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  gwLinkUser; //网关登陆sp时所用的用户名
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  gwLinkPwd; //网关登陆sp时所用的密码
  }


2、函数字符集属性错误,正确做法:

  [DllImport("UniAPIDll.dll", EntryPoint = "InitSgipAPI", CharSet = CharSet.Ansi)]
  public static extern int InitSgipAPI(StringBuilder path, ref LoginInfo pLoginInfo);
--------------------编程问答-------------------- 两个问题:
1、结构体映射错误,正确做法:

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,Pack=1)]
  public struct LoginInfo
  {
     public uint spNodeId; //sp的设备代码,应该由网关为其分配
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
     public string gwIp; //网关的侦听IP地址
     public int gwPort; //网关的侦听端口
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  loginGwUser; //sp登陆网关时所用的用户名
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  loginGwPwd; //sp登陆网关时所用的密码
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
     public string  appIp; //sp的侦听IP地址
     public int appPort; //sp的侦听端口
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  gwLinkUser; //网关登陆sp时所用的用户名
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
     public string  gwLinkPwd; //网关登陆sp时所用的密码
  }


2、函数字符集属性错误,正确做法:

  [DllImport("UniAPIDll.dll", EntryPoint = "InitSgipAPI", CharSet = CharSet.Ansi)]
  public static extern int InitSgipAPI(StringBuilder path, ref LoginInfo pLoginInfo);
--------------------编程问答--------------------
引用 6 楼 sdl2005lyx 的回复:
两个问题:
1、结构体映射错误,正确做法:
C# code

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,Pack=1)]
  public struct LoginInfo
  {
     public uint spNodeId; //sp的设备代码,应该由网关为其分配
     [MarshalAs(U……


依然会包内存错误。。。我之前这样试过。。 --------------------编程问答--------------------
引用 6 楼 sdl2005lyx 的回复:
两个问题:
1、结构体映射错误,正确做法:
C# code

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,Pack=1)]
  public struct LoginInfo
  {
     public uint spNodeId; //sp的设备代码,应该由网关为其分配
     [MarshalAs(U……


依然报错。 --------------------编程问答-------------------- [Quote=引用 6 楼 sdl2005lyx 的回复:]

sdl2005lyx

大侠,我之前这样写过,依然是报内存错误。。

--------------------编程问答-------------------- 用一个简单办法:在C++那边用sizeof,C#这边用Marshal.Sizeof,

对比两边的结构体大小是否一致! --------------------编程问答-------------------- 现在问题是,多种方法都试过了,依然是内存错误,有能真正执行通过的代码吗?
大小是一致的啊,里面有C的头文件。 --------------------编程问答-------------------- 如果这个dll跟硬件无关,你可以发给我:sdl2002lyx@163.com --------------------编程问答-------------------- 是要发短信吗? --------------------编程问答--------------------
引用 13 楼 ooo7880000 的回复:
是要发短信吗?


恩,调用联通网关,合作接口。 --------------------编程问答--------------------
引用 14 楼 drskysleep 的回复:
引用 13 楼 ooo7880000 的回复:

是要发短信吗?


恩,调用联通网关,合作接口。


联通还要这样呀,学到了,电信是我们发送一些XML信息到,电信给的短信通道,我们提供短信内容,发送人等,电信负责发送
--------------------编程问答-------------------- 有始有终,真的没人知道吗? --------------------编程问答-------------------- 发短信,用webservice --------------------编程问答-------------------- lz,你会不会用VC,会的话,你直接用Vc写个测试程序。。。 --------------------编程问答-------------------- 需要用C#直接调用。。。

如果可以用VC就没问题了

DLL确定没有问题,是通用的。 --------------------编程问答-------------------- 这是我用VC写的测试程序,运行也有问题,你这样,不是有个Demo程序吗,
你发过来,我看看它是怎么使用的!
    LoginInfo info;
    info.spNodeId = 3002300000;
    strcpy(info.gwIp ," ");
    info.gwPort = 9001;
    strcpy(info.loginGwUser, " ");
    strcpy(info.loginGwPwd , " ");
    strcpy(info.appIp , " ");
    info.appPort = 8000;
    strcpy(info.gwLinkUser , " ");
    strcpy(info.gwLinkPwd, " ");

    int size=sizeof(LoginInfo);

    HMODULE hMod=LoadLibrary("UniAPIDll.dll");

    typedef int (*FunAddr)(char* path, LoginInfo *pLoginInfo);
    FunAddr fun = (FunAddr)GetProcAddress(hMod, "InitSgipAPI");
    if(!fun)
    {
        MessageBox("获取函数地址失败!");
        return FALSE;
    }
    int ret=fun("E:\\test\\ExamDlg",&info); //这里一样报错! --------------------编程问答-------------------- --------------------编程问答-------------------- 这个是通用的API接口,之前看到论坛上也有不少朋友在问,有调用成功的吗? --------------------编程问答-------------------- --------------------编程问答-------------------- 没有.net的调用接口么?
移动的都有,直接调用就行了
联通的如果是通用的,就比较麻烦了
需要把所有的数据类型重新定义以下。
c#才能使用定以后的函数。 --------------------编程问答-------------------- 很多时候C# 对于C或者C++的参数错误!LZ要仔细检查,这种问题麻烦 --------------------编程问答-------------------- 无语了,都是加油回复。。有大侠调试通过的吗? --------------------编程问答-------------------- 始终无法正常写LOG。。 --------------------编程问答-------------------- C#和C++参数类型对照表。

还想请教个问题,联通或移动的网关接口,个人有权限调用么? --------------------编程问答-------------------- 我现在也碰到这个问题,也几乎尝试了各种能想到的数据类型,还是不行。。。楼主问题解决了吗?怎么解决的? --------------------编程问答-------------------- 库跟你的也是一样的。。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,