==>十万火急,平台调用问题(C#调C++DLL的参数传递问题)...在线等....

时间:2022-08-31 09:24:44
问题描述比较复杂,善心的朋友加我QQ 24358512 MSN flovein2000@163.com
--------------------
C#调用c++DLL

下面一段代码是C++自定义的结构原型:
struct cmppe_submit{
char icp_id  [CMPPE_MAX_ICP_ID_LEN+1]; /* 服务商代码   */
char svc_type[CMPPE_MAX_SVC_LEN+1]; /* 服务类型     */
dpl_uint8_t fee_type; /* 计费类型     */
dpl_uint32_t info_fee; /* 信息费       */
dpl_uint8_t proto_id; /* 协议ID GSM3.4*/
dpl_uint8_t msg_mode; /* 消息模式 */
dpl_uint8_t priority; /* 优先级别     */
char validate[CMPPE_DATETIME_LEN+1]; /* 过期时间     */
char schedule[CMPPE_DATETIME_LEN+1]; /* 调度时间     */
dpl_uint8_t fee_utype; /* 计费用户类型 */
char fee_user [CMPPE_MAX_MSISDN_LEN+1]; /* 被计费的用户 */
char src_addr [CMPPE_MAX_MSISDN_LEN+1]; /* 源用户 */
dpl_uint8_t du_count; /* 目的数量 */
char dst_addr[CMPPE_MAX_DSTS_NUM][CMPPE_MAX_MSISDN_LEN+1]; /* 目的用户 */
dpl_uint8_t data_coding; /* 数据编码     */
dpl_uint8_t sm_len; /* 消息长度     */
char short_msg[CMPPE_MAX_SM_LEN+1]; /* 短消息内容   */
};

下面是我自己用C#改写的结构声明:
[StructLayout(LayoutKind.Sequential)]
public class cmppe_submit
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
public string icp_id ; /* 服务商代码   *///定长数组= new char[esp.CMPPE_MAX_ICP_ID_LEN + 1] 6
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=11)]
public string svc_type; /* 服务类型     *///定长数组[CMPPE_MAX_SVC_LEN+1] 10
public char fee_type; /* 计费类型     *///@@无符号
public int info_fee; /* 信息费       *///@@无符号
public char proto_id; /* 协议ID GSM3.4*///@@无符号
public char msg_mode; /* 消息模式 *///@@无符号
public char priority; /* 优先级别     *///@@无符号
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=17)]
public string validate; /* 过期时间     *///[CMPPE_DATETIME_LEN+1] 16
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=17)]
public string schedule; /* 调度时间     *///[CMPPE_DATETIME_LEN+1] 16
public char fee_utype; /* 计费用户类型 *///@@有符号型
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=21)]
public string fee_user; /* 被计费的用户 */// [CMPPE_MAX_MSISDN_LEN+1]  20
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=21)]
public string src_addr ; /* 源用户 *///[CMPPE_MAX_MSISDN_LEN+1] 20
public char du_count; /* 目的数量 *///@@无符号
// [MarshalAs(UnmanagedType.ByValTStr, SizeConst=21)]
public char[][] dst_addr; /* 目的用户 *///@@[CMPPE_MAX_DSTS_NUM][CMPPE_MAX_MSISDN_LEN+1] 14,20
public char data_coding; /* 数据编码     *///@@无符号
public char sm_len; /* 消息长度     *///@@无符号
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=101)]
public string short_msg; /* 短消息内容   *///[CMPPE_MAX_SM_LEN+1] 100
}

下面是C++事例中的一个函数,目的是对上面C++定义结构进行赋值

/设置发送手机号及发送内容
dpl_status_t submit_value_set(cmppe_submit *cs)//cs短信消息体结构
{
char usr1[3][20] = {"13673377870","13733820234","13733820234"};
int j;

cmppe_submit_sm_init(cs);//数据包初始化  返回dpl_status_t (int型)类型的常量DPL_SUCCESS
cmppe_submit_sm_set_shortmsg(cs, "省端口程序测试,博思特信息技术有限公司", 38);//设置提交请求中的短消息内容,参数(消息结构体,内容小于160字符,短信息长度)
cmppe_submit_sm_set_priority(cs, 0);//设置提交请求中优先级域的内容 参数 (请求包,优先级(<9)
cmppe_submit_sm_set_msgmode (cs, 1);//设置提交请求包中消息模式域的内容 参数(请求包,消息模式:0-不需要状态报告, 1-需要状态报告,2-控制类型消息)
cmppe_submit_sm_set_protoid (cs, 1);//****设置提交请求包中协议号信息 参数(请求包,unsigned char协议号)
cmppe_submit_sm_set_dcs     (cs, 15);//设置提交请求包中短消息编码域的值 参数(请求包,unsigned char 短信息编码格式)
cmppe_submit_sm_set_schedule(cs, "");//****设置提交请求包中短消息调度时间域的值 参数(请求包,const char发送时间)const char 为 char 类型存储为双字节的Unicode 字符
cmppe_submit_sm_set_validate(cs, "");//*****设置提交请求包中短消息存活时间域的值
cmppe_submit_sm_set_src_addr(cs, "13733820234");//设置提交请求中源地址域值
for(j=0;j<3;j++){
cmppe_submit_sm_add_dst_addr(cs, usr1[j]); //向提交请求包中添加一个接收用户的手机号
}
cmppe_submit_sm_set_icp_id  (cs, "916707");//设置提交请求包中icp_id域值
cmppe_submit_sm_set_svc_type(cs, "9410");//****设置提交请求包中服务类型域的值 可以是任何可见的ASCII字符
cmppe_submit_sm_set_fee_type(cs, 1);//设置提交请求包中资费类别域值
cmppe_submit_sm_set_info_fee(cs, 3);//设置提交请求包中资费代码域的值 以分为单位,值范围0-999999
cmppe_submit_sm_set_fee_user(cs, 1, "13733820234");//设置提交请求包中计费用户的相关信息 计费用户类型字段,0:对目的终端MSISDN计费;1:对源终端MSISDN计费;2:对SP计费;3:表示本字段无效,对谁计费参见fee_usr字段。

return DPL_SUCCESS;//设置结果情况反馈
}

下面是我用C#改写的函数,功能同上

//设置发送手机号及发送内容
private int submit_value_set(ref cmppe_submit cs)//cs短信消息体结构
{
// cs.icp_id="007";
            string[] usr1=new string[3] {"13673377870","13733820234","13733820234"};
int j;
esp.cmppe_submit_sm_init(cs);//数据包初始化  返回dpl_status_t (int型)类型的常量DPL_SUCCESS
esp.cmppe_submit_sm_set_shortmsg(cs, "省端口程序测试,博思特信息技术有限公司", 38);//设置提交请求中的短消息内容,参数(消息结构体,内容小于160字符,短信息长度)
esp.cmppe_submit_sm_set_priority(cs, 0);//设置提交请求中优先级域的内容 参数 (请求包,优先级(<9)
esp.cmppe_submit_sm_set_msgmode (cs, 1);//设置提交请求包中消息模式域的内容 参数(请求包,消息模式:0-不需要状态报告, 1-需要状态报告,2-控制类型消息)
esp.cmppe_submit_sm_set_protoid (cs, 1);//****设置提交请求包中协议号信息 参数(请求包,unsigned char协议号)
esp.cmppe_submit_sm_set_dcs(cs, 15);//设置提交请求包中短消息编码域的值 参数(请求包,unsigned char 短信息编码格式)
esp.cmppe_submit_sm_set_schedule(cs, "");//****设置提交请求包中短消息调度时间域的值 参数(请求包,const char发送时间)const char 为 char 类型存储为双字节的Unicode 字符
esp.cmppe_submit_sm_set_validate(cs, "");//*****设置提交请求包中短消息存活时间域的值
esp.cmppe_submit_sm_set_src_addr(cs, "13733820234");//设置提交请求中源地址域值
for(j=0;j<3;j++)
{
esp.cmppe_submit_sm_add_dst_addr(cs,"13733820234"); //向提交请求包中添加一个接收用户的手机号
}
esp.cmppe_submit_sm_set_icp_id(cs, "916707");//设置提交请求包中icp_id域值
esp.cmppe_submit_sm_set_svc_type(cs, "9410");//****设置提交请求包中服务类型域的值 可以是任何可见的ASCII字符
esp.cmppe_submit_sm_set_fee_type(cs, 1);//设置提交请求包中资费类别域值
esp.cmppe_submit_sm_set_info_fee(cs, 3);//设置提交请求包中资费代码域的值 以分为单位,值范围0-999999
esp.cmppe_submit_sm_set_fee_user(cs, 1, "13733820234");//设置提交请求包中计费用户的相关信息 计费用户类型字段,0:对目的终端MSISDN计费;1:对源终端MSISDN计费;2:对SP计费;3:表示本字段无效,对谁计费参见fee_usr字段。

return DPL_SUCCESS;//设置结果情况反馈
}

问题:我的C#运行到
esp.cmppe_submit_sm_add_dst_addr(cs,"13733820234"); //向提交请求包中添加一个接收用户的手机号

时出错,错误提示是:未处理的“System.NullReferenceException”类型的异常出现在 esp.exe 中。
其他信息: 未将对象引用设置到对象的实例。

注意:出错的语句是给结构的 public char[][] dst_addr; /* 目的用户
赋值的,它是一个二维数组,而我在C#写调用函数时把 C++事例的
char usr1[3][20] = {"13673377870","13733820234","13733820234"};
改成了
         string[] usr1=new string[3] {"13673377870","13733820234","13733820234"};

5 个解决方案

#1


救命....

#2


顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶

#3


using System.Runtime.InteropServices;
.................................


[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
unsafe struct VSPPPacketHead
{
public int PacketLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]  public string Catagory;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]  public string SubCommand;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]  public string OpCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] public string SeqNO;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]  public string SPID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string ServerID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string OperateID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string CallingNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string CalledNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string Result;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string CryType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string KeyNO;
}

#4


以上是如何使用c++的结构 难点在字符数组上面
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]  public string Catagory;

这个里面虽然是指明为string类型
但实际是StringBuilder类型的,使用的时候得勇 Catagory.ToString()
这样

其他的类型主意一下长度就可以了

#5


结构中间有一个二维数组
char dst_addr[CMPPE_MAX_DSTS_NUM][CMPPE_MAX_MSISDN_LEN+1]; /* 目的用户*/

请问 二维数组用C#怎么写啊?

#1


救命....

#2


顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶

#3


using System.Runtime.InteropServices;
.................................


[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
unsafe struct VSPPPacketHead
{
public int PacketLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]  public string Catagory;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]  public string SubCommand;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]  public string OpCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] public string SeqNO;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]  public string SPID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string ServerID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string OperateID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string CallingNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string CalledNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string Result;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string CryType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]  public string KeyNO;
}

#4


以上是如何使用c++的结构 难点在字符数组上面
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]  public string Catagory;

这个里面虽然是指明为string类型
但实际是StringBuilder类型的,使用的时候得勇 Catagory.ToString()
这样

其他的类型主意一下长度就可以了

#5


结构中间有一个二维数组
char dst_addr[CMPPE_MAX_DSTS_NUM][CMPPE_MAX_MSISDN_LEN+1]; /* 目的用户*/

请问 二维数组用C#怎么写啊?